es2fTextureFormatTests.cpp revision 469002caa1ccd58f59f53a1bf3dbac4cf6a5d817
1/*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 2.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 "es2fTextureFormatTests.hpp"
37#include "glsTextureTestUtil.hpp"
38#include "gluTexture.hpp"
39#include "gluStrUtil.hpp"
40#include "gluTextureUtil.hpp"
41#include "gluPixelTransfer.hpp"
42#include "tcuTestLog.hpp"
43#include "tcuTextureUtil.hpp"
44
45#include "deStringUtil.hpp"
46
47#include "glwEnums.hpp"
48#include "glwFunctions.hpp"
49
50namespace deqp
51{
52namespace gles2
53{
54namespace Functional
55{
56
57using tcu::TestLog;
58using std::vector;
59using std::string;
60using tcu::Sampler;
61using namespace glu;
62using namespace gls::TextureTestUtil;
63
64// Texture2DFormatCase
65
66class Texture2DFormatCase : public tcu::TestCase
67{
68public:
69							Texture2DFormatCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, 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	const deUint32			m_format;
83	const deUint32			m_dataType;
84	const int				m_width;
85	const 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.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
100{
101}
102
103Texture2DFormatCase::~Texture2DFormatCase (void)
104{
105	deinit();
106}
107
108void Texture2DFormatCase::init (void)
109{
110	TestLog&				log		= m_testCtx.getLog();
111	tcu::TextureFormat		fmt		= glu::mapGLTransferFormat(m_format, m_dataType);
112	tcu::TextureFormatInfo	spec	= tcu::getTextureFormatInfo(fmt);
113	std::ostringstream		fmtName;
114
115	fmtName << getPixelFormatStr(m_format) << ", " << getTypeStr(m_dataType);
116
117	log << TestLog::Message << "2D texture, " << fmtName.str() << ", " << m_width << "x" << m_height
118							<< ",\n  fill with " << formatGradient(&spec.valueMin, &spec.valueMax) << " gradient"
119		<< TestLog::EndMessage;
120
121	m_texture = new Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height);
122
123	// Fill level 0.
124	m_texture->getRefTexture().allocLevel(0);
125	tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), spec.valueMin, spec.valueMax);
126}
127
128void Texture2DFormatCase::deinit (void)
129{
130	delete m_texture;
131	m_texture = DE_NULL;
132
133	m_renderer.clear();
134}
135
136Texture2DFormatCase::IterateResult Texture2DFormatCase::iterate (void)
137{
138	TestLog&				log					= m_testCtx.getLog();
139	const glw::Functions&	gl					= m_renderCtx.getFunctions();
140	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_width, m_height, deStringHash(getName()));
141	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
142	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
143	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
144	vector<float>			texCoord;
145	ReferenceParams			renderParams		(TEXTURETYPE_2D);
146	tcu::TextureFormatInfo	spec				= tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
147	const deUint32			wrapS				= GL_CLAMP_TO_EDGE;
148	const deUint32			wrapT				= GL_CLAMP_TO_EDGE;
149	const deUint32			minFilter			= GL_NEAREST;
150	const deUint32			magFilter			= GL_NEAREST;
151
152	renderParams.flags			|= RenderParams::LOG_ALL;
153	renderParams.samplerType	= getSamplerType(m_texture->getRefTexture().getFormat());
154	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
155	renderParams.colorScale		= spec.lookupScale;
156	renderParams.colorBias		= spec.lookupBias;
157
158	computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
159
160	log << TestLog::Message << "Texture parameters:"
161							<< "\n  WRAP_S = " << getTextureParameterValueStr(GL_TEXTURE_WRAP_S, wrapS)
162							<< "\n  WRAP_T = " << getTextureParameterValueStr(GL_TEXTURE_WRAP_T, wrapT)
163							<< "\n  MIN_FILTER = " << getTextureParameterValueStr(GL_TEXTURE_MIN_FILTER, minFilter)
164							<< "\n  MAG_FILTER = " << getTextureParameterValueStr(GL_TEXTURE_MAG_FILTER, magFilter)
165		<< TestLog::EndMessage;
166
167	// Setup base viewport.
168	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
169
170	// Upload texture data to GL.
171	m_texture->upload();
172
173	// Bind to unit 0.
174	gl.activeTexture(GL_TEXTURE0);
175	gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
176
177	// Setup nearest neighbor filtering and clamp-to-edge.
178	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
179	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
180	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
181	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
182
183	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
184
185	// Draw.
186	m_renderer.renderQuad(0, &texCoord[0], renderParams);
187	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
188	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
189
190	// Compute reference.
191	sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], renderParams);
192
193	// Compare and log.
194	bool isOk = compareImages(log, referenceFrame, renderedFrame, threshold);
195
196	m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
197							isOk ? "Pass"				: "Image comparison failed");
198
199	return STOP;
200}
201
202// TextureCubeFormatCase
203
204class TextureCubeFormatCase : public tcu::TestCase
205{
206public:
207							TextureCubeFormatCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height);
208							~TextureCubeFormatCase	(void);
209
210	void					init					(void);
211	void					deinit					(void);
212	IterateResult			iterate					(void);
213
214private:
215							TextureCubeFormatCase	(const TextureCubeFormatCase& other);
216	TextureCubeFormatCase&	operator=				(const TextureCubeFormatCase& other);
217
218	bool					testFace				(tcu::CubeFace face);
219
220	glu::RenderContext&		m_renderCtx;
221
222	const deUint32			m_format;
223	const deUint32			m_dataType;
224	const int				m_width;
225	const int				m_height;
226
227	glu::TextureCube*		m_texture;
228	TextureRenderer			m_renderer;
229
230	int						m_curFace;
231	bool					m_isOk;
232};
233
234
235TextureCubeFormatCase::TextureCubeFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height)
236	: TestCase		(testCtx, name, description)
237	, m_renderCtx	(renderCtx)
238	, m_format		(format)
239	, m_dataType	(dataType)
240	, m_width		(width)
241	, m_height		(height)
242	, m_texture		(DE_NULL)
243	, m_renderer	(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
244	, m_curFace		(0)
245	, m_isOk		(false)
246{
247}
248
249TextureCubeFormatCase::~TextureCubeFormatCase (void)
250{
251	deinit();
252}
253
254void TextureCubeFormatCase::init (void)
255{
256	TestLog&				log		= m_testCtx.getLog();
257	tcu::TextureFormat		fmt		= glu::mapGLTransferFormat(m_format, m_dataType);
258	tcu::TextureFormatInfo	spec	= tcu::getTextureFormatInfo(fmt);
259	std::ostringstream		fmtName;
260
261	if (m_dataType)
262		fmtName << getPixelFormatStr(m_format) << ", " << getTypeStr(m_dataType);
263	else
264		fmtName << getPixelFormatStr(m_format);
265
266	log << TestLog::Message << "Cube map texture, " << fmtName.str() << ", " << m_width << "x" << m_height
267							<< ",\n  fill with " << formatGradient(&spec.valueMin, &spec.valueMax) << " gradient"
268		<< TestLog::EndMessage;
269
270	DE_ASSERT(m_width == m_height);
271	m_texture = m_dataType != GL_NONE
272			  ? new TextureCube(m_renderCtx, m_format, m_dataType, m_width)	// Implicit internal format.
273		      : new TextureCube(m_renderCtx, m_format, m_width);				// Explicit internal format.
274
275	// Fill level 0.
276	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
277	{
278		tcu::Vec4 gMin, gMax;
279
280		switch (face)
281		{
282			case 0: gMin = spec.valueMin.swizzle(0, 1, 2, 3); gMax = spec.valueMax.swizzle(0, 1, 2, 3); break;
283			case 1: gMin = spec.valueMin.swizzle(2, 1, 0, 3); gMax = spec.valueMax.swizzle(2, 1, 0, 3); break;
284			case 2: gMin = spec.valueMin.swizzle(1, 2, 0, 3); gMax = spec.valueMax.swizzle(1, 2, 0, 3); break;
285			case 3: gMin = spec.valueMax.swizzle(0, 1, 2, 3); gMax = spec.valueMin.swizzle(0, 1, 2, 3); break;
286			case 4: gMin = spec.valueMax.swizzle(2, 1, 0, 3); gMax = spec.valueMin.swizzle(2, 1, 0, 3); break;
287			case 5: gMin = spec.valueMax.swizzle(1, 2, 0, 3); gMax = spec.valueMin.swizzle(1, 2, 0, 3); break;
288			default:
289				DE_ASSERT(false);
290		}
291
292		m_texture->getRefTexture().allocLevel((tcu::CubeFace)face, 0);
293		tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevelFace(0, (tcu::CubeFace)face), gMin, gMax);
294	}
295
296	// Upload texture data to GL.
297	m_texture->upload();
298
299	// Initialize iteration state.
300	m_curFace	= 0;
301	m_isOk		= true;
302}
303
304void TextureCubeFormatCase::deinit (void)
305{
306	delete m_texture;
307	m_texture = DE_NULL;
308
309	m_renderer.clear();
310}
311
312bool TextureCubeFormatCase::testFace (tcu::CubeFace face)
313{
314	const glw::Functions&	gl					= m_renderCtx.getFunctions();
315	TestLog&				log					= m_testCtx.getLog();
316	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_width, m_height, deStringHash(getName())+(deUint32)face);
317	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
318	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
319	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
320	vector<float>			texCoord;
321	ReferenceParams			renderParams		(TEXTURETYPE_CUBE);
322	tcu::TextureFormatInfo	spec				= tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
323
324	renderParams.samplerType				= getSamplerType(m_texture->getRefTexture().getFormat());
325	renderParams.sampler					= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
326	renderParams.sampler.seamlessCubeMap	= false;
327	renderParams.colorScale					= spec.lookupScale;
328	renderParams.colorBias					= spec.lookupBias;
329
330	// Log render info on first face.
331	if (face == tcu::CUBEFACE_NEGATIVE_X)
332		renderParams.flags |= RenderParams::LOG_ALL;
333
334	computeQuadTexCoordCube(texCoord, face);
335
336	// \todo [2011-10-28 pyry] Image set name / section?
337	log << TestLog::Message << face << TestLog::EndMessage;
338
339	// Setup base viewport.
340	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
341
342	// Bind to unit 0.
343	gl.activeTexture(GL_TEXTURE0);
344	gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());
345
346	// Setup nearest neighbor filtering and clamp-to-edge.
347	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
348	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
349	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
350	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
351
352	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
353
354	m_renderer.renderQuad(0, &texCoord[0], renderParams);
355	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
356	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
357
358	// Compute reference.
359	sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], renderParams);
360
361	// Compare and log.
362	return compareImages(log, referenceFrame, renderedFrame, threshold);
363}
364
365TextureCubeFormatCase::IterateResult TextureCubeFormatCase::iterate (void)
366{
367	// Execute test for all faces.
368	if (!testFace((tcu::CubeFace)m_curFace))
369		m_isOk = false;
370
371	m_curFace += 1;
372
373	if (m_curFace == tcu::CUBEFACE_LAST)
374	{
375		m_testCtx.setTestResult(m_isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
376								m_isOk ? "Pass"					: "Image comparison failed");
377		return STOP;
378	}
379	else
380		return CONTINUE;
381}
382
383TextureFormatTests::TextureFormatTests (Context& context)
384	: TestCaseGroup(context, "format", "Texture Format Tests")
385{
386}
387
388TextureFormatTests::~TextureFormatTests (void)
389{
390}
391
392// Compressed2DFormatCase
393
394class Compressed2DFormatCase : public tcu::TestCase
395{
396public:
397								Compressed2DFormatCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& renderCtxInfo, const char* name, const char* description, const std::vector<std::string>& filenames);
398								~Compressed2DFormatCase		(void);
399
400	void						init						(void);
401	void						deinit						(void);
402	IterateResult				iterate						(void);
403
404private:
405								Compressed2DFormatCase		(const Compressed2DFormatCase& other);
406	Compressed2DFormatCase&		operator=					(const Compressed2DFormatCase& other);
407
408	glu::RenderContext&			m_renderCtx;
409	const glu::ContextInfo&		m_renderCtxInfo;
410
411	std::vector<std::string>	m_filenames;
412
413	glu::Texture2D*				m_texture;
414	TextureRenderer				m_renderer;
415};
416
417Compressed2DFormatCase::Compressed2DFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& renderCtxInfo, const char* name, const char* description, const std::vector<std::string>& filenames)
418	: TestCase			(testCtx, name, description)
419	, m_renderCtx		(renderCtx)
420	, m_renderCtxInfo	(renderCtxInfo)
421	, m_filenames		(filenames)
422	, m_texture			(DE_NULL)
423	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
424{
425}
426
427Compressed2DFormatCase::~Compressed2DFormatCase (void)
428{
429	deinit();
430}
431
432void Compressed2DFormatCase::init (void)
433{
434	// Create texture.
435	m_texture = Texture2D::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size(), m_filenames);
436}
437
438void Compressed2DFormatCase::deinit (void)
439{
440	delete m_texture;
441	m_texture = DE_NULL;
442
443	m_renderer.clear();
444}
445
446Compressed2DFormatCase::IterateResult Compressed2DFormatCase::iterate (void)
447{
448	const glw::Functions&	gl					= m_renderCtx.getFunctions();
449	TestLog&				log					= m_testCtx.getLog();
450	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_texture->getRefTexture().getWidth(), m_texture->getRefTexture().getHeight(), deStringHash(getName()));
451	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
452	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
453	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
454	vector<float>			texCoord;
455
456	computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
457
458	// Setup base viewport.
459	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
460
461	// Bind to unit 0.
462	gl.activeTexture(GL_TEXTURE0);
463	gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());
464
465	// Setup nearest neighbor filtering and clamp-to-edge.
466	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
467	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
468	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
469	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
470
471	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
472
473	// Draw.
474	m_renderer.renderQuad(0, &texCoord[0], TEXTURETYPE_2D);
475	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
476	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
477
478	// Compute reference.
479	ReferenceParams refParams(TEXTURETYPE_2D);
480	refParams.sampler = Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
481	sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], refParams);
482
483	// Compare and log.
484	bool isOk = compareImages(log, referenceFrame, renderedFrame, threshold);
485
486	m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
487							isOk ? "Pass"				: "Image comparison failed");
488
489	return STOP;
490}
491
492// CompressedCubeFormatCase
493
494class CompressedCubeFormatCase : public tcu::TestCase
495{
496public:
497								CompressedCubeFormatCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& renderCtxInfo, const char* name, const char* description, const std::vector<std::string>& filenames);
498								~CompressedCubeFormatCase	(void);
499
500	void						init						(void);
501	void						deinit						(void);
502	IterateResult				iterate						(void);
503
504private:
505								CompressedCubeFormatCase	(const CompressedCubeFormatCase& other);
506	CompressedCubeFormatCase&	operator=					(const CompressedCubeFormatCase& other);
507
508	bool						testFace					(tcu::CubeFace face);
509
510	glu::RenderContext&			m_renderCtx;
511	const glu::ContextInfo&		m_renderCtxInfo;
512
513	std::vector<std::string>	m_filenames;
514
515	glu::TextureCube*			m_texture;
516	TextureRenderer				m_renderer;
517
518	int							m_curFace;
519	bool						m_isOk;
520};
521
522CompressedCubeFormatCase::CompressedCubeFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& renderCtxInfo, const char* name, const char* description, const std::vector<std::string>& filenames)
523	: TestCase			(testCtx, name, description)
524	, m_renderCtx		(renderCtx)
525	, m_renderCtxInfo	(renderCtxInfo)
526	, m_filenames		(filenames)
527	, m_texture			(DE_NULL)
528	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
529	, m_curFace			(0)
530	, m_isOk			(false)
531{
532}
533
534CompressedCubeFormatCase::~CompressedCubeFormatCase (void)
535{
536	deinit();
537}
538
539void CompressedCubeFormatCase::init (void)
540{
541	// Create texture.
542	DE_ASSERT(m_filenames.size() % 6 == 0);
543	m_texture = TextureCube::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size()/6, m_filenames);
544
545	m_curFace	= 0;
546	m_isOk		= true;
547}
548
549void CompressedCubeFormatCase::deinit (void)
550{
551	delete m_texture;
552	m_texture = DE_NULL;
553
554	m_renderer.clear();
555}
556
557bool CompressedCubeFormatCase::testFace (tcu::CubeFace face)
558{
559	const glw::Functions&	gl					= m_renderCtx.getFunctions();
560	TestLog&				log					= m_testCtx.getLog();
561	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_texture->getRefTexture().getSize(), m_texture->getRefTexture().getSize(), deStringHash(getName())+(deUint32)face);
562	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
563	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
564	Sampler					sampler				(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
565	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
566	vector<float>			texCoord;
567
568	computeQuadTexCoordCube(texCoord, face);
569
570	// \todo [2011-10-28 pyry] Image set name / section?
571	log << TestLog::Message << face << TestLog::EndMessage;
572
573	// Setup base viewport.
574	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
575
576	// Bind to unit 0.
577	gl.activeTexture(GL_TEXTURE0);
578	gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());
579
580	// Setup nearest neighbor filtering and clamp-to-edge.
581	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
582	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
583	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
584	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
585
586	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");
587
588	m_renderer.renderQuad(0, &texCoord[0], TEXTURETYPE_CUBE);
589	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
590	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
591
592	// Compute reference.
593	sampleTexture(SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], ReferenceParams(TEXTURETYPE_CUBE, sampler));
594
595	// Compare and log.
596	return compareImages(log, referenceFrame, renderedFrame, threshold);
597}
598
599CompressedCubeFormatCase::IterateResult CompressedCubeFormatCase::iterate (void)
600{
601	// Execute test for all faces.
602	if (!testFace((tcu::CubeFace)m_curFace))
603		m_isOk = false;
604
605	m_curFace += 1;
606
607	if (m_curFace == tcu::CUBEFACE_LAST)
608	{
609		m_testCtx.setTestResult(m_isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
610								m_isOk ? "Pass"					: "Image comparison failed");
611		return STOP;
612	}
613	else
614		return CONTINUE;
615}
616
617vector<string> toStringVector (const char* const* str, int numStr)
618{
619	vector<string> v;
620	v.resize(numStr);
621	for (int i = 0; i < numStr; i++)
622		v[i] = str[i];
623	return v;
624}
625
626void TextureFormatTests::init (void)
627{
628	struct
629	{
630		const char*	name;
631		deUint32		format;
632		deUint32		dataType;
633	} texFormats[] =
634	{
635		{ "a8",			GL_ALPHA,			GL_UNSIGNED_BYTE },
636		{ "l8",			GL_LUMINANCE,		GL_UNSIGNED_BYTE },
637		{ "la88",		GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE },
638		{ "rgb565",		GL_RGB,				GL_UNSIGNED_SHORT_5_6_5 },
639		{ "rgb888",		GL_RGB,				GL_UNSIGNED_BYTE },
640		{ "rgba4444",	GL_RGBA,			GL_UNSIGNED_SHORT_4_4_4_4 },
641		{ "rgba5551",	GL_RGBA,			GL_UNSIGNED_SHORT_5_5_5_1 },
642		{ "rgba8888",	GL_RGBA,			GL_UNSIGNED_BYTE }
643	};
644
645	for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(texFormats); formatNdx++)
646	{
647		deUint32	format			= texFormats[formatNdx].format;
648		deUint32	dataType		= texFormats[formatNdx].dataType;
649		string	nameBase		= texFormats[formatNdx].name;
650		string	descriptionBase	= string(glu::getPixelFormatName(format)) + ", " + glu::getTypeName(dataType);
651
652		addChild(new Texture2DFormatCase	(m_testCtx, m_context.getRenderContext(),	(nameBase + "_2d_pot").c_str(),		(descriptionBase + ", GL_TEXTURE_2D").c_str(),			format, dataType, 128, 128));
653		addChild(new Texture2DFormatCase	(m_testCtx, m_context.getRenderContext(),	(nameBase + "_2d_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D").c_str(),			format, dataType,  63, 112));
654		addChild(new TextureCubeFormatCase	(m_testCtx, m_context.getRenderContext(),	(nameBase + "_cube_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	format, dataType,  64,  64));
655		addChild(new TextureCubeFormatCase	(m_testCtx, m_context.getRenderContext(),	(nameBase + "_cube_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	format, dataType,  57,  57));
656	}
657
658	// ETC-1 compressed formats.
659	{
660		static const char* filenames[] =
661		{
662			"data/etc1/photo_helsinki_mip_0.pkm",
663			"data/etc1/photo_helsinki_mip_1.pkm",
664			"data/etc1/photo_helsinki_mip_2.pkm",
665			"data/etc1/photo_helsinki_mip_3.pkm",
666			"data/etc1/photo_helsinki_mip_4.pkm",
667			"data/etc1/photo_helsinki_mip_5.pkm",
668			"data/etc1/photo_helsinki_mip_6.pkm",
669			"data/etc1/photo_helsinki_mip_7.pkm"
670		};
671		addChild(new Compressed2DFormatCase(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))));
672	}
673
674	{
675		vector<string> filenames;
676		filenames.push_back("data/etc1/photo_helsinki_113x89.pkm");
677		addChild(new Compressed2DFormatCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), "etc1_2d_npot", "GL_ETC1_RGB8_OES, GL_TEXTURE_2D", filenames));
678	}
679
680	{
681		static const char* faceExt[] = { "neg_x", "pos_x", "neg_y", "pos_y", "neg_z", "pos_z" };
682
683		const int		potNumLevels	= 7;
684		vector<string>	potFilenames;
685		for (int level = 0; level < potNumLevels; level++)
686			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
687				potFilenames.push_back(string("data/etc1/skybox_") + faceExt[face] + "_mip_" + de::toString(level) + ".pkm");
688
689		addChild(new CompressedCubeFormatCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), "etc1_cube_pot", "GL_ETC1_RGB8_OES, GL_TEXTURE_CUBE_MAP", potFilenames));
690
691		vector<string> npotFilenames;
692		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
693			npotFilenames.push_back(string("data/etc1/skybox_61x61_") + faceExt[face] + ".pkm");
694
695		addChild(new CompressedCubeFormatCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), "etc1_cube_npot", "GL_ETC_RGB8_OES, GL_TEXTURE_CUBE_MAP", npotFilenames));
696	}
697}
698
699} // Functional
700} // gles2
701} // deqp
702