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