Home | History | Annotate | Download | only in functional
      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 
     50 namespace deqp
     51 {
     52 namespace gles2
     53 {
     54 namespace Functional
     55 {
     56 
     57 using tcu::TestLog;
     58 using std::vector;
     59 using std::string;
     60 using tcu::Sampler;
     61 using namespace glu;
     62 using namespace gls::TextureTestUtil;
     63 
     64 // Texture2DFormatCase
     65 
     66 class Texture2DFormatCase : public tcu::TestCase
     67 {
     68 public:
     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 
     76 private:
     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 
     91 Texture2DFormatCase::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_100_ES, glu::PRECISION_MEDIUMP)
    100 {
    101 }
    102 
    103 Texture2DFormatCase::~Texture2DFormatCase (void)
    104 {
    105 	deinit();
    106 }
    107 
    108 void 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 
    128 void Texture2DFormatCase::deinit (void)
    129 {
    130 	delete m_texture;
    131 	m_texture = DE_NULL;
    132 
    133 	m_renderer.clear();
    134 }
    135 
    136 Texture2DFormatCase::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 
    204 class TextureCubeFormatCase : public tcu::TestCase
    205 {
    206 public:
    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 
    214 private:
    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 
    235 TextureCubeFormatCase::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, glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
    244 	, m_curFace		(0)
    245 	, m_isOk		(false)
    246 {
    247 }
    248 
    249 TextureCubeFormatCase::~TextureCubeFormatCase (void)
    250 {
    251 	deinit();
    252 }
    253 
    254 void 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 
    304 void TextureCubeFormatCase::deinit (void)
    305 {
    306 	delete m_texture;
    307 	m_texture = DE_NULL;
    308 
    309 	m_renderer.clear();
    310 }
    311 
    312 bool 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 
    365 TextureCubeFormatCase::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 
    383 TextureFormatTests::TextureFormatTests (Context& context)
    384 	: TestCaseGroup(context, "format", "Texture Format Tests")
    385 {
    386 }
    387 
    388 TextureFormatTests::~TextureFormatTests (void)
    389 {
    390 }
    391 
    392 // Compressed2DFormatCase
    393 
    394 class Compressed2DFormatCase : public tcu::TestCase
    395 {
    396 public:
    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 
    404 private:
    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 
    417 Compressed2DFormatCase::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, glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
    424 {
    425 }
    426 
    427 Compressed2DFormatCase::~Compressed2DFormatCase (void)
    428 {
    429 	deinit();
    430 }
    431 
    432 void 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 
    438 void Compressed2DFormatCase::deinit (void)
    439 {
    440 	delete m_texture;
    441 	m_texture = DE_NULL;
    442 
    443 	m_renderer.clear();
    444 }
    445 
    446 Compressed2DFormatCase::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 
    494 class CompressedCubeFormatCase : public tcu::TestCase
    495 {
    496 public:
    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 
    504 private:
    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 
    522 CompressedCubeFormatCase::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, glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
    529 	, m_curFace			(0)
    530 	, m_isOk			(false)
    531 {
    532 }
    533 
    534 CompressedCubeFormatCase::~CompressedCubeFormatCase (void)
    535 {
    536 	deinit();
    537 }
    538 
    539 void 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 
    549 void CompressedCubeFormatCase::deinit (void)
    550 {
    551 	delete m_texture;
    552 	m_texture = DE_NULL;
    553 
    554 	m_renderer.clear();
    555 }
    556 
    557 bool 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 
    599 CompressedCubeFormatCase::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 
    617 vector<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 
    626 void 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