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 "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 
     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 
    105 Texture2DFormatCase::~Texture2DFormatCase (void)
    106 {
    107 	deinit();
    108 }
    109 
    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 
    130 void Texture2DFormatCase::deinit (void)
    131 {
    132 	delete m_texture;
    133 	m_texture = DE_NULL;
    134 
    135 	m_renderer.clear();
    136 }
    137 
    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 
    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 
    251 TextureCubeFormatCase::~TextureCubeFormatCase (void)
    252 {
    253 	deinit();
    254 }
    255 
    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 
    306 void TextureCubeFormatCase::deinit (void)
    307 {
    308 	delete m_texture;
    309 	m_texture = DE_NULL;
    310 
    311 	m_renderer.clear();
    312 }
    313 
    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 
    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 
    385 TextureFormatTests::TextureFormatTests (Context& context)
    386 	: TestCaseGroup(context, "format", "Texture Format Tests")
    387 {
    388 }
    389 
    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 
    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 
    429 Compressed2DFormatCase::~Compressed2DFormatCase (void)
    430 {
    431 	deinit();
    432 }
    433 
    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 
    440 void Compressed2DFormatCase::deinit (void)
    441 {
    442 	delete m_texture;
    443 	m_texture = DE_NULL;
    444 
    445 	m_renderer.clear();
    446 }
    447 
    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 
    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 
    536 CompressedCubeFormatCase::~CompressedCubeFormatCase (void)
    537 {
    538 	deinit();
    539 }
    540 
    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 
    551 void CompressedCubeFormatCase::deinit (void)
    552 {
    553 	delete m_texture;
    554 	m_texture = DE_NULL;
    555 
    556 	m_renderer.clear();
    557 }
    558 
    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 
    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 
    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 
    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