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 completeness tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es2fTextureCompletenessTests.hpp"
     25 #include "glsTextureTestUtil.hpp"
     26 
     27 #include "tcuTestLog.hpp"
     28 #include "tcuSurface.hpp"
     29 #include "tcuImageCompare.hpp"
     30 #include "tcuVector.hpp"
     31 #include "tcuTextureUtil.hpp"
     32 #include "tcuRenderTarget.hpp"
     33 
     34 #include "deRandom.hpp"
     35 #include "deMath.h"
     36 #include "deInt32.h"
     37 #include "deString.h"
     38 
     39 #include "gluTextureUtil.hpp"
     40 #include "gluPixelTransfer.hpp"
     41 #include "gluContextInfo.hpp"
     42 #include "gluRenderContext.hpp"
     43 
     44 #include "glw.h"
     45 
     46 namespace deqp
     47 {
     48 namespace gles2
     49 {
     50 namespace Functional
     51 {
     52 
     53 using std::vector;
     54 using std::string;
     55 using tcu::TestLog;
     56 using tcu::TextureFormat;
     57 using tcu::Sampler;
     58 using tcu::IVec2;
     59 using tcu::RGBA;
     60 using gls::TextureTestUtil::TextureRenderer;
     61 using gls::TextureTestUtil::computeQuadTexCoord2D;
     62 using gls::TextureTestUtil::computeQuadTexCoordCube;
     63 
     64 static const GLenum s_cubeTargets[] =
     65 {
     66 	GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
     67 	GL_TEXTURE_CUBE_MAP_POSITIVE_X,
     68 	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
     69 	GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
     70 	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
     71 	GL_TEXTURE_CUBE_MAP_POSITIVE_Z
     72 };
     73 
     74 static bool isExtensionSupported (const glu::ContextInfo& ctxInfo, const char* extension)
     75 {
     76 	vector<string> extensions = ctxInfo.getExtensions();
     77 
     78 	for (vector<string>::iterator iter = extensions.begin(); iter != extensions.end(); ++iter)
     79 		if (iter->compare(extension) == 0)
     80 			return true;
     81 
     82 	return false;
     83 }
     84 
     85 static bool compareToConstantColor (TestLog& log, const char* imageSetName, const char* imageSetDesc, const tcu::Surface& result, tcu::CompareLogMode logMode, RGBA color)
     86 {
     87 	bool isOk = true;
     88 
     89 	for (int y = 0; y < result.getHeight(); y++)
     90 	{
     91 		for (int x = 0; x < result.getWidth(); x++)
     92 		{
     93 			if (result.getPixel(x, y).getRed()		!= color.getRed()	||
     94 				result.getPixel(x, y).getGreen()	!= color.getGreen() ||
     95 				result.getPixel(x, y).getBlue()		!= color.getBlue()	||
     96 				result.getPixel(x, y).getAlpha()	!= color.getAlpha())
     97 			{
     98 				isOk = false;
     99 			}
    100 		}
    101 	}
    102 
    103 	if (!isOk || logMode == tcu::COMPARE_LOG_EVERYTHING)
    104 	{
    105 		if (!isOk)
    106 			log << TestLog::Message << "Image comparison failed" << TestLog::EndMessage;
    107 
    108 		log << TestLog::ImageSet(imageSetName, imageSetDesc)
    109 			<< TestLog::Image("Result",		"Result",		result)
    110 			<< TestLog::EndImageSet;
    111 	}
    112 	else if (logMode == tcu::COMPARE_LOG_RESULT)
    113 		log << TestLog::ImageSet(imageSetName, imageSetDesc)
    114 			<< TestLog::Image("Result",		"Result",		result)
    115 			<< TestLog::EndImageSet;
    116 
    117 	return isOk;
    118 }
    119 
    120 // Base classes.
    121 
    122 class Tex2DCompletenessCase : public tcu::TestCase
    123 {
    124 public:
    125 							Tex2DCompletenessCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description);
    126 							~Tex2DCompletenessCase	(void) {};
    127 
    128 	IterateResult			iterate					(void);
    129 
    130 protected:
    131 	virtual void			createTexture			(void) = 0;
    132 
    133 	tcu::TestContext&		m_testCtx;
    134 	glu::RenderContext&		m_renderCtx;
    135 	RGBA					m_compareColor;
    136 };
    137 
    138 Tex2DCompletenessCase::Tex2DCompletenessCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description)
    139 	: TestCase			(testCtx, name, description)
    140 	, m_testCtx			(testCtx)
    141 	, m_renderCtx		(renderCtx)
    142 	, m_compareColor	(RGBA(0,0,0,255))
    143 {
    144 }
    145 
    146 Tex2DCompletenessCase::IterateResult Tex2DCompletenessCase::iterate (void)
    147 {
    148 	int					viewportWidth	= de::min(64, m_renderCtx.getRenderTarget().getWidth());
    149 	int					viewportHeight	= de::min(64, m_renderCtx.getRenderTarget().getHeight());
    150 	TestLog&			log				= m_testCtx.getLog();
    151 	TextureRenderer		renderer		(m_renderCtx, log, glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP);
    152 	tcu::Surface		renderedFrame	(viewportWidth, viewportHeight);
    153 	vector<float>		texCoord;
    154 
    155 	de::Random			random			(deStringHash(getName()));
    156 	int					offsetX			= random.getInt(0, m_renderCtx.getRenderTarget().getWidth()		- viewportWidth	);
    157 	int					offsetY			= random.getInt(0, m_renderCtx.getRenderTarget().getHeight()	- viewportHeight);
    158 
    159 	computeQuadTexCoord2D	(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
    160 
    161 	glViewport				(offsetX, offsetY, viewportWidth, viewportHeight);
    162 
    163 	createTexture			();
    164 	renderer.renderQuad		(0, &texCoord[0], gls::TextureTestUtil::TEXTURETYPE_2D);
    165 	glu::readPixels			(m_renderCtx, offsetX, offsetY, renderedFrame.getAccess());
    166 
    167 	bool isOk = compareToConstantColor(log, "Result", "Image comparison result", renderedFrame, tcu::COMPARE_LOG_RESULT, m_compareColor);
    168 
    169 	m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
    170 							isOk ? "Pass"				: "Image comparison failed");
    171 	return STOP;
    172 }
    173 
    174 class TexCubeCompletenessCase : public tcu::TestCase
    175 {
    176 public:
    177 							TexCubeCompletenessCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description);
    178 							~TexCubeCompletenessCase	(void) {};
    179 
    180 	IterateResult			iterate						(void);
    181 
    182 protected:
    183 	virtual void			createTexture				(void) = 0;
    184 
    185 	tcu::TestContext&		m_testCtx;
    186 	glu::RenderContext&		m_renderCtx;
    187 	RGBA					m_compareColor;
    188 };
    189 
    190 TexCubeCompletenessCase::TexCubeCompletenessCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description)
    191 	: TestCase			(testCtx, name, description)
    192 	, m_testCtx			(testCtx)
    193 	, m_renderCtx		(renderCtx)
    194 	, m_compareColor	(RGBA(0,0,0,255))
    195 {
    196 }
    197 
    198 TexCubeCompletenessCase::IterateResult TexCubeCompletenessCase::iterate (void)
    199 {
    200 	int					viewportWidth	= de::min(64, m_renderCtx.getRenderTarget().getWidth());
    201 	int					viewportHeight	= de::min(64, m_renderCtx.getRenderTarget().getHeight());
    202 	bool				allFacesOk		= true;
    203 	TestLog&			log				= m_testCtx.getLog();
    204 	TextureRenderer		renderer		(m_renderCtx, log, glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP);
    205 	tcu::Surface		renderedFrame	(viewportWidth, viewportHeight);
    206 	vector<float>		texCoord;
    207 
    208 	de::Random			random			(deStringHash(getName()));
    209 	int					offsetX			= random.getInt(0, de::max(0,m_renderCtx.getRenderTarget().getWidth()	- 64));
    210 	int					offsetY			= random.getInt(0, de::max(0,m_renderCtx.getRenderTarget().getHeight()	- 64));
    211 
    212 	createTexture();
    213 
    214 	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
    215 	{
    216 		computeQuadTexCoordCube	(texCoord, (tcu::CubeFace)face);
    217 
    218 		glViewport				(offsetX, offsetY, viewportWidth, viewportHeight);
    219 
    220 		renderer.renderQuad		(0, &texCoord[0], gls::TextureTestUtil::TEXTURETYPE_CUBE);
    221 		glu::readPixels			(m_renderCtx, offsetX, offsetY, renderedFrame.getAccess());
    222 
    223 		bool isOk = compareToConstantColor(log, "Result", "Image comparison result", renderedFrame, tcu::COMPARE_LOG_RESULT, m_compareColor);
    224 
    225 		if (!isOk)
    226 			allFacesOk = false;
    227 	}
    228 
    229 	m_testCtx.setTestResult(allFacesOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
    230 							allFacesOk ? "Pass"					: "Image comparison failed");
    231 	return STOP;
    232 }
    233 
    234 // Texture 2D tests.
    235 
    236 class Incomplete2DSizeCase : public Tex2DCompletenessCase
    237 {
    238 public:
    239 								Incomplete2DSizeCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx, const glu::ContextInfo& ctxInfo);
    240 								~Incomplete2DSizeCase	(void) {}
    241 
    242 	virtual void				createTexture			(void);
    243 
    244 private:
    245 	int							m_invalidLevelNdx;
    246 	IVec2						m_invalidLevelSize;
    247 	const glu::ContextInfo&		m_ctxInfo;
    248 	IVec2						m_size;
    249 };
    250 
    251 Incomplete2DSizeCase::Incomplete2DSizeCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx, const glu::ContextInfo& ctxInfo)
    252 	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
    253 	, m_invalidLevelNdx			(invalidLevelNdx)
    254 	, m_invalidLevelSize		(invalidLevelSize)
    255 	, m_ctxInfo					(ctxInfo)
    256 	, m_size					(size)
    257 {
    258 }
    259 
    260 void Incomplete2DSizeCase::createTexture (void)
    261 {
    262 	static const char* const s_relaxingExtensions[] =
    263 	{
    264 		"GL_OES_texture_npot",
    265 		"GL_NV_texture_npot_2D_mipmap",
    266 	};
    267 
    268 	tcu::TextureFormat		fmt				= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
    269 	tcu::TextureLevel		levelData		(fmt);
    270 	TestLog&				log				= m_testCtx.getLog();
    271 
    272 	GLuint texture;
    273 	glGenTextures	(1, &texture);
    274 	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
    275 	glBindTexture	(GL_TEXTURE_2D, texture);
    276 
    277 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
    278 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
    279 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
    280 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
    281 
    282 	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
    283 
    284 	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
    285 	{
    286 		int	levelW = (levelNdx == m_invalidLevelNdx) ? m_invalidLevelSize.x() : de::max(1, m_size.x() >> levelNdx);
    287 		int	levelH = (levelNdx == m_invalidLevelNdx) ? m_invalidLevelSize.y() : de::max(1, m_size.y() >> levelNdx);
    288 
    289 		levelData.setSize(m_size.x(), m_size.y());
    290 		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
    291 
    292 		glTexImage2D(GL_TEXTURE_2D, levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
    293 	}
    294 
    295 	GLU_CHECK_MSG("Set texturing state");
    296 
    297 	// If size not allowed in core, search for relaxing extensions
    298 	if (!deIsPowerOfTwo32(m_size.x()) && !deIsPowerOfTwo32(m_size.y()))
    299 	{
    300 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_relaxingExtensions); ++ndx)
    301 		{
    302 			if (isExtensionSupported(m_ctxInfo, s_relaxingExtensions[ndx]))
    303 			{
    304 				log << TestLog::Message << s_relaxingExtensions[ndx] << " supported, assuming completeness test to pass." << TestLog::EndMessage;
    305 				m_compareColor = RGBA(0,0,255,255);
    306 				break;
    307 			}
    308 		}
    309 	}
    310 }
    311 
    312 class Incomplete2DFormatCase : public Tex2DCompletenessCase
    313 {
    314 public:
    315 							Incomplete2DFormatCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat, int invalidLevelNdx);
    316 							~Incomplete2DFormatCase	(void) {}
    317 
    318 	virtual void			createTexture			(void);
    319 
    320 private:
    321 	int						m_invalidLevelNdx;
    322 	deUint32				m_format;
    323 	deUint32				m_invalidFormat;
    324 	IVec2					m_size;
    325 };
    326 
    327 Incomplete2DFormatCase::Incomplete2DFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat, int invalidLevelNdx)
    328 	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
    329 	, m_invalidLevelNdx			(invalidLevelNdx)
    330 	, m_format					(format)
    331 	, m_invalidFormat			(invalidFormat)
    332 	, m_size					(size)
    333 {
    334 }
    335 
    336 void Incomplete2DFormatCase::createTexture (void)
    337 {
    338 	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(m_format, GL_UNSIGNED_BYTE);
    339 	tcu::TextureLevel	levelData	(fmt);
    340 
    341 	GLuint texture;
    342 	glGenTextures	(1, &texture);
    343 	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
    344 	glBindTexture	(GL_TEXTURE_2D, texture);
    345 
    346 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
    347 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
    348 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
    349 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
    350 
    351 	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
    352 
    353 	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
    354 	{
    355 		int	levelW = de::max(1, m_size.x() >> levelNdx);
    356 		int	levelH = de::max(1, m_size.y() >> levelNdx);
    357 
    358 		levelData.setSize(m_size.x(), m_size.y());
    359 		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
    360 
    361 		deUint32 format = levelNdx == m_invalidLevelNdx ? m_invalidFormat : m_format;
    362 
    363 		glTexImage2D(GL_TEXTURE_2D, levelNdx, format, levelW, levelH, 0, format, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
    364 	}
    365 
    366 	GLU_CHECK_MSG("Set texturing state");
    367 }
    368 
    369 class Incomplete2DMissingLevelCase : public Tex2DCompletenessCase
    370 {
    371 public:
    372 						Incomplete2DMissingLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int missingLevelNdx);
    373 						~Incomplete2DMissingLevelCase	(void) {}
    374 
    375 	virtual void		createTexture					(void);
    376 
    377 private:
    378 	int					m_missingLevelNdx;
    379 	IVec2				m_size;
    380 };
    381 
    382 Incomplete2DMissingLevelCase::Incomplete2DMissingLevelCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int missingLevelNdx)
    383 	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
    384 	, m_missingLevelNdx			(missingLevelNdx)
    385 	, m_size					(size)
    386 {
    387 }
    388 
    389 void Incomplete2DMissingLevelCase::createTexture (void)
    390 {
    391 	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
    392 	tcu::TextureLevel	levelData	(fmt);
    393 
    394 	GLuint texture;
    395 	glGenTextures	(1, &texture);
    396 	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
    397 	glBindTexture	(GL_TEXTURE_2D, texture);
    398 
    399 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
    400 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
    401 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
    402 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
    403 
    404 	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
    405 
    406 	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
    407 	{
    408 		levelData.setSize(m_size.x(), m_size.y());
    409 		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
    410 
    411 		int	levelW = de::max(1, m_size.x() >> levelNdx);
    412 		int	levelH = de::max(1, m_size.y() >> levelNdx);
    413 
    414 		// Skip specified level.
    415 		if (levelNdx != m_missingLevelNdx)
    416 			glTexImage2D(GL_TEXTURE_2D, levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
    417 	}
    418 
    419 	GLU_CHECK_MSG("Set texturing state");
    420 }
    421 
    422 class Incomplete2DWrapModeCase : public Tex2DCompletenessCase
    423 {
    424 public:
    425 								Incomplete2DWrapModeCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 wrapT, deUint32 wrapS, const glu::ContextInfo& ctxInfo);
    426 								~Incomplete2DWrapModeCase	(void) {}
    427 
    428 	virtual void				createTexture				(void);
    429 
    430 private:
    431 	deUint32					m_wrapT;
    432 	deUint32					m_wrapS;
    433 	const glu::ContextInfo&		m_ctxInfo;
    434 	IVec2						m_size;
    435 };
    436 
    437 Incomplete2DWrapModeCase::Incomplete2DWrapModeCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 wrapT, deUint32 wrapS, const glu::ContextInfo& ctxInfo)
    438 	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
    439 	, m_wrapT					(wrapT)
    440 	, m_wrapS					(wrapS)
    441 	, m_ctxInfo					(ctxInfo)
    442 	, m_size					(size)
    443 {
    444 }
    445 
    446 void Incomplete2DWrapModeCase::createTexture (void)
    447 {
    448 	TestLog&			log			= m_testCtx.getLog();
    449 	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
    450 	tcu::TextureLevel	levelData	(fmt);
    451 
    452 	GLuint texture;
    453 	glGenTextures(1, &texture);
    454 	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    455 	glBindTexture(GL_TEXTURE_2D, texture);
    456 
    457 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
    458 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
    459 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
    460 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
    461 
    462 	levelData.setSize(m_size.x(), m_size.y());
    463 	clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
    464 
    465 	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_size.x(), m_size.y(), 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
    466 
    467 	GLU_CHECK_MSG("Set texturing state");
    468 
    469 	const char* extension = "GL_OES_texture_npot";
    470 	if (isExtensionSupported(m_ctxInfo, extension))
    471 	{
    472 		log << TestLog::Message << extension << " supported, assuming completeness test to pass." << TestLog::EndMessage;
    473 		m_compareColor = RGBA(0,0,255,255);
    474 	}
    475 }
    476 
    477 class Complete2DExtraLevelCase : public Tex2DCompletenessCase
    478 {
    479 public:
    480 						Complete2DExtraLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size);
    481 						~Complete2DExtraLevelCase	(void) {}
    482 
    483 	virtual void		createTexture				(void);
    484 
    485 private:
    486 	IVec2				m_size;
    487 };
    488 
    489 Complete2DExtraLevelCase::Complete2DExtraLevelCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size)
    490 	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
    491 	, m_size					(size)
    492 {
    493 }
    494 
    495 void Complete2DExtraLevelCase::createTexture (void)
    496 {
    497 	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
    498 	tcu::TextureLevel	levelData	(fmt);
    499 
    500 	GLuint texture;
    501 	glGenTextures	(1, &texture);
    502 	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
    503 	glBindTexture	(GL_TEXTURE_2D, texture);
    504 
    505 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
    506 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
    507 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
    508 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
    509 
    510 	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
    511 
    512 	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
    513 	{
    514 		int	levelW = de::max(1, m_size.x() >> levelNdx);
    515 		int	levelH = de::max(1, m_size.y() >> levelNdx);
    516 
    517 		levelData.setSize(m_size.x(), m_size.y());
    518 		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
    519 
    520 		glTexImage2D(GL_TEXTURE_2D, levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
    521 	}
    522 
    523 	// Specify extra level.
    524 	glTexImage2D(GL_TEXTURE_2D, numLevels+1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
    525 	m_compareColor = RGBA(0,0,255,255);
    526 
    527 	GLU_CHECK_MSG("Set texturing state");
    528 }
    529 
    530 class Incomplete2DEmptyObjectCase : public Tex2DCompletenessCase
    531 {
    532 public:
    533 						Incomplete2DEmptyObjectCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size);
    534 						~Incomplete2DEmptyObjectCase	(void) {}
    535 
    536 	virtual void		createTexture					(void);
    537 
    538 private:
    539 	IVec2				m_size;
    540 };
    541 
    542 Incomplete2DEmptyObjectCase::Incomplete2DEmptyObjectCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size)
    543 	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
    544 	, m_size					(size)
    545 {
    546 }
    547 
    548 void Incomplete2DEmptyObjectCase::createTexture (void)
    549 {
    550 	GLuint texture;
    551 	glGenTextures	(1, &texture);
    552 	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
    553 	glBindTexture	(GL_TEXTURE_2D, texture);
    554 
    555 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
    556 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
    557 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
    558 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
    559 
    560 	GLU_CHECK_MSG("Set texturing state");
    561 }
    562 
    563 // Cube texture tests.
    564 
    565 class IncompleteCubeSizeCase : public TexCubeCompletenessCase
    566 {
    567 public:
    568 							IncompleteCubeSizeCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx);
    569 							IncompleteCubeSizeCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx, tcu::CubeFace invalidCubeFace);
    570 							~IncompleteCubeSizeCase	(void) {}
    571 
    572 	virtual void			createTexture			(void);
    573 
    574 private:
    575 	int						m_invalidLevelNdx;
    576 	IVec2					m_invalidLevelSize;
    577 	tcu::CubeFace			m_invalidCubeFace;
    578 	IVec2					m_size;
    579 };
    580 
    581 IncompleteCubeSizeCase::IncompleteCubeSizeCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx)
    582 	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
    583 	, m_invalidLevelNdx				(invalidLevelNdx)
    584 	, m_invalidLevelSize			(invalidLevelSize)
    585 	, m_invalidCubeFace				(tcu::CUBEFACE_LAST)
    586 	, m_size						(size)
    587 {
    588 }
    589 
    590 IncompleteCubeSizeCase::IncompleteCubeSizeCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx, tcu::CubeFace invalidCubeFace)
    591 	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
    592 	, m_invalidLevelNdx				(invalidLevelNdx)
    593 	, m_invalidLevelSize			(invalidLevelSize)
    594 	, m_invalidCubeFace				(invalidCubeFace)
    595 	, m_size						(size)
    596 {
    597 }
    598 
    599 void IncompleteCubeSizeCase::createTexture (void)
    600 {
    601 	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
    602 	tcu::TextureLevel	levelData	(fmt);
    603 
    604 	GLuint texture;
    605 	glGenTextures	(1, &texture);
    606 	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
    607 	glBindTexture	(GL_TEXTURE_CUBE_MAP, texture);
    608 
    609 	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		GL_REPEAT);
    610 	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		GL_REPEAT);
    611 	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
    612 	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
    613 
    614 	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
    615 
    616 	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
    617 	{
    618 		levelData.setSize(m_size.x(), m_size.y());
    619 		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
    620 
    621 		for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
    622 		{
    623 			int levelW = de::max(1, m_size.x() >> levelNdx);
    624 			int levelH = de::max(1, m_size.y() >> levelNdx);
    625 			if (levelNdx == m_invalidLevelNdx && (m_invalidCubeFace == tcu::CUBEFACE_LAST || m_invalidCubeFace == targetNdx))
    626 			{
    627 				levelW =  m_invalidLevelSize.x();
    628 				levelH =  m_invalidLevelSize.y();
    629 			}
    630 			glTexImage2D(s_cubeTargets[targetNdx], levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
    631 		}
    632 	}
    633 
    634 	GLU_CHECK_MSG("Set texturing state");
    635 }
    636 
    637 class IncompleteCubeFormatCase : public TexCubeCompletenessCase
    638 {
    639 public:
    640 							IncompleteCubeFormatCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat);
    641 							IncompleteCubeFormatCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat, tcu::CubeFace invalidCubeFace);
    642 							~IncompleteCubeFormatCase	(void) {}
    643 
    644 	virtual void			createTexture				(void);
    645 
    646 private:
    647 	deUint32				m_format;
    648 	deUint32				m_invalidFormat;
    649 	tcu::CubeFace			m_invalidCubeFace;
    650 	IVec2					m_size;
    651 };
    652 
    653 IncompleteCubeFormatCase::IncompleteCubeFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat)
    654 	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
    655 	, m_format						(format)
    656 	, m_invalidFormat				(invalidFormat)
    657 	, m_invalidCubeFace				(tcu::CUBEFACE_LAST)
    658 	, m_size						(size)
    659 {
    660 }
    661 
    662 IncompleteCubeFormatCase::IncompleteCubeFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat, tcu::CubeFace invalidCubeFace)
    663 	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
    664 	, m_format						(format)
    665 	, m_invalidFormat				(invalidFormat)
    666 	, m_invalidCubeFace				(invalidCubeFace)
    667 	, m_size						(size)
    668 {
    669 }
    670 
    671 void IncompleteCubeFormatCase::createTexture (void)
    672 {
    673 	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
    674 	tcu::TextureLevel	levelData	(fmt);
    675 
    676 	GLuint texture;
    677 	glGenTextures	(1, &texture);
    678 	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
    679 	glBindTexture	(GL_TEXTURE_CUBE_MAP, texture);
    680 
    681 	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		GL_REPEAT);
    682 	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		GL_REPEAT);
    683 	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
    684 	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
    685 
    686 	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
    687 
    688 	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
    689 	{
    690 		levelData.setSize(m_size.x(), m_size.y());
    691 		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
    692 
    693 		int	levelW = de::max(1, m_size.x() >> levelNdx);
    694 		int	levelH = de::max(1, m_size.y() >> levelNdx);
    695 
    696 		for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
    697 		{
    698 			deUint32 format = m_format;
    699 			if (levelNdx == 0 && (m_invalidCubeFace == tcu::CUBEFACE_LAST || m_invalidCubeFace == targetNdx))
    700 				format = m_invalidFormat;
    701 
    702 			glTexImage2D(s_cubeTargets[targetNdx], levelNdx, format, levelW, levelH, 0, format, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
    703 		}
    704 	}
    705 
    706 	GLU_CHECK_MSG("Set texturing state");
    707 }
    708 
    709 class IncompleteCubeMissingLevelCase : public TexCubeCompletenessCase
    710 {
    711 public:
    712 							IncompleteCubeMissingLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int invalidLevelNdx);
    713 							IncompleteCubeMissingLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int invalidLevelNdx, tcu::CubeFace invalidCubeFace);
    714 							~IncompleteCubeMissingLevelCase	(void) {}
    715 
    716 	virtual void			createTexture					(void);
    717 
    718 private:
    719 	int						m_invalidLevelNdx;
    720 	tcu::CubeFace			m_invalidCubeFace;
    721 	IVec2					m_size;
    722 };
    723 
    724 IncompleteCubeMissingLevelCase::IncompleteCubeMissingLevelCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int invalidLevelNdx)
    725 	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
    726 	, m_invalidLevelNdx				(invalidLevelNdx)
    727 	, m_invalidCubeFace				(tcu::CUBEFACE_LAST)
    728 	, m_size						(size)
    729 {
    730 }
    731 
    732 IncompleteCubeMissingLevelCase::IncompleteCubeMissingLevelCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int invalidLevelNdx, tcu::CubeFace invalidCubeFace)
    733 	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
    734 	, m_invalidLevelNdx				(invalidLevelNdx)
    735 	, m_invalidCubeFace				(invalidCubeFace)
    736 	, m_size						(size)
    737 {
    738 }
    739 
    740 void IncompleteCubeMissingLevelCase::createTexture (void)
    741 {
    742 	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
    743 	tcu::TextureLevel	levelData	(fmt);
    744 
    745 	GLuint texture;
    746 	glGenTextures	(1, &texture);
    747 	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
    748 	glBindTexture	(GL_TEXTURE_CUBE_MAP, texture);
    749 
    750 	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		GL_REPEAT);
    751 	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		GL_REPEAT);
    752 	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
    753 	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
    754 
    755 	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
    756 
    757 	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
    758 	{
    759 		levelData.setSize(m_size.x(), m_size.y());
    760 		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
    761 
    762 		int	levelW = (levelNdx == m_invalidLevelNdx) ? m_size.x() : de::max(1, m_size.x() >> levelNdx);
    763 		int	levelH = (levelNdx == m_invalidLevelNdx) ? m_size.y() : de::max(1, m_size.y() >> levelNdx);
    764 
    765 		if (levelNdx != m_invalidLevelNdx || m_invalidCubeFace != tcu::CUBEFACE_LAST)
    766 		{
    767 			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
    768 			{
    769 				// If single cubeface is specified then skip only that one.
    770 				if (m_invalidCubeFace != targetNdx)
    771 					glTexImage2D(s_cubeTargets[targetNdx], levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
    772 			}
    773 		}
    774 	}
    775 
    776 	GLU_CHECK_MSG("Set texturing state");
    777 }
    778 
    779 class IncompleteCubeWrapModeCase : public TexCubeCompletenessCase
    780 {
    781 public:
    782 								IncompleteCubeWrapModeCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 wrapT, deUint32 wrapS, const glu::ContextInfo& ctxInfo);
    783 								~IncompleteCubeWrapModeCase	(void) {}
    784 
    785 	virtual void				createTexture				(void);
    786 
    787 private:
    788 	deUint32					m_wrapT;
    789 	deUint32					m_wrapS;
    790 	const glu::ContextInfo&		m_ctxInfo;
    791 	IVec2						m_size;
    792 };
    793 
    794 IncompleteCubeWrapModeCase::IncompleteCubeWrapModeCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 wrapT, deUint32 wrapS, const glu::ContextInfo& ctxInfo)
    795 	: TexCubeCompletenessCase	(testCtx, renderCtx, name, description)
    796 	, m_wrapT					(wrapT)
    797 	, m_wrapS					(wrapS)
    798 	, m_ctxInfo					(ctxInfo)
    799 	, m_size					(size)
    800 {
    801 }
    802 
    803 void IncompleteCubeWrapModeCase::createTexture (void)
    804 {
    805 	TestLog&			log			= m_testCtx.getLog();
    806 	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
    807 	tcu::TextureLevel	levelData	(fmt);
    808 
    809 	GLuint texture;
    810 	glGenTextures(1, &texture);
    811 	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    812 	glBindTexture(GL_TEXTURE_2D, texture);
    813 
    814 	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		m_wrapS);
    815 	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		m_wrapT);
    816 	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
    817 	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
    818 
    819 	levelData.setSize(m_size.x(), m_size.y());
    820 	clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
    821 
    822 	for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
    823 		glTexImage2D(s_cubeTargets[targetNdx], 0, GL_RGBA, m_size.x(), m_size.y(), 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
    824 
    825 	GLU_CHECK_MSG("Set texturing state");
    826 
    827 	const char* extension = "GL_OES_texture_npot";
    828 	if (isExtensionSupported(m_ctxInfo, extension))
    829 	{
    830 		log << TestLog::Message << extension << " supported, assuming completeness test to pass." << TestLog::EndMessage;
    831 		m_compareColor = RGBA(0,0,255,255);
    832 	}
    833 }
    834 
    835 class CompleteCubeExtraLevelCase : public TexCubeCompletenessCase
    836 {
    837 public:
    838 						CompleteCubeExtraLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size);
    839 						~CompleteCubeExtraLevelCase	(void) {}
    840 
    841 	virtual void		createTexture				(void);
    842 
    843 private:
    844 	IVec2				m_size;
    845 };
    846 
    847 CompleteCubeExtraLevelCase::CompleteCubeExtraLevelCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size)
    848 	: TexCubeCompletenessCase	(testCtx, renderCtx, name, description)
    849 	, m_size					(size)
    850 {
    851 }
    852 
    853 void CompleteCubeExtraLevelCase::createTexture (void)
    854 {
    855 	tcu::TextureFormat		fmt				= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
    856 	tcu::TextureLevel		levelData		(fmt);
    857 
    858 	GLuint texture;
    859 	glGenTextures	(1, &texture);
    860 	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
    861 	glBindTexture	(GL_TEXTURE_2D, texture);
    862 
    863 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
    864 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
    865 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
    866 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
    867 
    868 	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));
    869 
    870 	levelData.setSize(m_size.x(), m_size.y());
    871 	clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
    872 
    873 	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
    874 	{
    875 		int	levelW = de::max(1, m_size.x() >> levelNdx);
    876 		int	levelH = de::max(1, m_size.y() >> levelNdx);
    877 
    878 		for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
    879 			glTexImage2D(s_cubeTargets[targetNdx], levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
    880 	}
    881 
    882 	// Specify extra level.
    883 	for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
    884 		glTexImage2D(s_cubeTargets[targetNdx], numLevels+1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
    885 
    886 	m_compareColor = RGBA(0,0,255,255);
    887 
    888 	GLU_CHECK_MSG("Set texturing state");
    889 }
    890 
    891 class IncompleteCubeEmptyObjectCase : public TexCubeCompletenessCase
    892 {
    893 public:
    894 							IncompleteCubeEmptyObjectCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size);
    895 							~IncompleteCubeEmptyObjectCase	(void) {}
    896 
    897 	virtual void			createTexture				(void);
    898 
    899 private:
    900 	IVec2					m_size;
    901 };
    902 
    903 IncompleteCubeEmptyObjectCase::IncompleteCubeEmptyObjectCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size)
    904 	: TexCubeCompletenessCase	(testCtx, renderCtx, name, description)
    905 	, m_size					(size)
    906 {
    907 }
    908 
    909 void IncompleteCubeEmptyObjectCase::createTexture (void)
    910 {
    911 	GLuint texture;
    912 	glGenTextures	(1, &texture);
    913 	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
    914 	glBindTexture	(GL_TEXTURE_2D, texture);
    915 
    916 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
    917 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
    918 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
    919 	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
    920 
    921 	GLU_CHECK_MSG("Set texturing state");
    922 }
    923 
    924 // Texture completeness group.
    925 
    926 TextureCompletenessTests::TextureCompletenessTests (Context& context)
    927 	: TestCaseGroup(context, "completeness", "Completeness tests")
    928 {
    929 }
    930 
    931 void TextureCompletenessTests::init (void)
    932 {
    933 	tcu::TestCaseGroup* tex2d = new tcu::TestCaseGroup(m_testCtx, "2d", "2D completeness");
    934 	addChild(tex2d);
    935 	tcu::TestCaseGroup* cube = new tcu::TestCaseGroup(m_testCtx, "cube", "Cubemap completeness");
    936 	addChild(cube);
    937 
    938 	// Texture 2D size.
    939 	tex2d->addChild(new Incomplete2DSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size",				"", IVec2(255, 255), IVec2(255, 255), 0, m_context.getContextInfo()));
    940 	tex2d->addChild(new Incomplete2DSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_0",		"", IVec2(256, 256), IVec2(255, 255), 0, m_context.getContextInfo()));
    941 	tex2d->addChild(new Incomplete2DSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_1",		"", IVec2(256, 256), IVec2(127, 127), 1, m_context.getContextInfo()));
    942 	tex2d->addChild(new Incomplete2DSizeCase(m_testCtx, m_context.getRenderContext(), "not_positive_level_0",	"", IVec2(256, 256), IVec2(0, 0),	  0, m_context.getContextInfo()));
    943 	// Texture 2D format.
    944 	tex2d->addChild(new Incomplete2DFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgb_rgba",						"", IVec2(128, 128), GL_RGB,				GL_RGBA,			1));
    945 	tex2d->addChild(new Incomplete2DFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgba_rgb",						"", IVec2(128, 128), GL_RGBA,				GL_RGB,				1));
    946 	tex2d->addChild(new Incomplete2DFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_luminance_luminance_alpha",	"", IVec2(128, 128), GL_LUMINANCE,			GL_LUMINANCE_ALPHA,	1));
    947 	tex2d->addChild(new Incomplete2DFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_luminance_alpha_luminance",	"", IVec2(128, 128), GL_LUMINANCE_ALPHA,	GL_LUMINANCE,		1));
    948 	// Texture 2D missing level.
    949 	tex2d->addChild(new Incomplete2DMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_1",			"", IVec2(128, 128),	1));
    950 	tex2d->addChild(new Incomplete2DMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_3",			"", IVec2(128, 128),	3));
    951 	tex2d->addChild(new Incomplete2DMissingLevelCase(m_testCtx, m_context.getRenderContext(), "last_level_missing",			"", IVec2(128, 64),		de::max(deLog2Floor32(128), deLog2Floor32(64))));
    952 	// Texture 2D wrap modes.
    953 	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_t_repeat",			"", IVec2(127, 127), GL_CLAMP_TO_EDGE,		GL_REPEAT,				m_context.getContextInfo()));
    954 	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_s_repeat",			"", IVec2(127, 127), GL_REPEAT,				GL_CLAMP_TO_EDGE,		m_context.getContextInfo()));
    955 	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_all_repeat",		"", IVec2(127, 127), GL_REPEAT,				GL_REPEAT,				m_context.getContextInfo()));
    956 	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_mirrored_repeat",	"", IVec2(127, 127), GL_MIRRORED_REPEAT,	GL_MIRRORED_REPEAT,		m_context.getContextInfo()));
    957 	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "repeat_width_npot",		"", IVec2(127, 128), GL_REPEAT,				GL_REPEAT,				m_context.getContextInfo()));
    958 	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "repeat_height_npot",		"", IVec2(128, 127), GL_REPEAT,				GL_REPEAT,				m_context.getContextInfo()));
    959 	// Texture 2D extra level.
    960 	tex2d->addChild(new Complete2DExtraLevelCase(m_testCtx, m_context.getRenderContext(), "extra_level", "", IVec2(64, 64)));
    961 	// Texture 2D empty object.
    962 	tex2d->addChild(new Incomplete2DEmptyObjectCase(m_testCtx, m_context.getRenderContext(), "empty_object", "", IVec2(64, 64)));
    963 
    964 	// Cube size.
    965 	cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_0",			"", IVec2(64, 64), IVec2(63, 63), 0));
    966 	cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_1",			"", IVec2(64, 64), IVec2(31, 31), 1));
    967 	cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_0_pos_x",	"", IVec2(64, 64), IVec2(63, 63), 0, tcu::CUBEFACE_POSITIVE_X));
    968 	cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_1_neg_x",	"", IVec2(64, 64), IVec2(31, 31), 1, tcu::CUBEFACE_NEGATIVE_X));
    969 	cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "not_positive_level_0",		"", IVec2(64, 64), IVec2(0,0)	, 0));
    970 	// Cube format.
    971 	cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgb_rgba_level_0",					"", IVec2(64, 64), GL_RGB,				GL_RGBA));
    972 	cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgba_rgb_level_0",					"", IVec2(64, 64), GL_RGBA,				GL_RGB));
    973 	cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_luminance_luminance_alpha_level_0",	"", IVec2(64, 64), GL_LUMINANCE,		GL_LUMINANCE_ALPHA));
    974 	cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_luminance_alpha_luminance_level_0",	"", IVec2(64, 64), GL_LUMINANCE_ALPHA,	GL_LUMINANCE));
    975 	cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgb_rgba_level_0_pos_z",				"", IVec2(64, 64), GL_RGB,				GL_RGBA,	tcu::CUBEFACE_POSITIVE_Z));
    976 	cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgba_rgb_level_0_neg_z",				"", IVec2(64, 64), GL_RGBA,				GL_RGB,		tcu::CUBEFACE_NEGATIVE_Z));
    977 	// Cube missing level.
    978 	cube->addChild(new IncompleteCubeMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_1",		"", IVec2(64, 64), 1));
    979 	cube->addChild(new IncompleteCubeMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_3",		"", IVec2(64, 64), 3));
    980 	cube->addChild(new IncompleteCubeMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_1_pos_y",	"", IVec2(64, 64), 1, tcu::CUBEFACE_POSITIVE_Y));
    981 	cube->addChild(new IncompleteCubeMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_3_neg_y",	"", IVec2(64, 64), 3, tcu::CUBEFACE_NEGATIVE_Y));
    982 	// Cube wrap modes.
    983 	cube->addChild(new IncompleteCubeWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_t_repeat",			"", IVec2(127, 127), GL_CLAMP_TO_EDGE,		GL_REPEAT,				m_context.getContextInfo()));
    984 	cube->addChild(new IncompleteCubeWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_s_repeat",			"", IVec2(127, 127), GL_REPEAT,				GL_CLAMP_TO_EDGE,		m_context.getContextInfo()));
    985 	cube->addChild(new IncompleteCubeWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_all_repeat",		"", IVec2(127, 127), GL_REPEAT,				GL_REPEAT,				m_context.getContextInfo()));
    986 	cube->addChild(new IncompleteCubeWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_mirrored_repeat",	"", IVec2(127, 127), GL_MIRRORED_REPEAT,	GL_MIRRORED_REPEAT,		m_context.getContextInfo()));
    987 	// Cube extra level.
    988 	cube->addChild(new CompleteCubeExtraLevelCase(m_testCtx, m_context.getRenderContext(), "extra_level", "", IVec2(64, 64)));
    989 	// Cube extra level.
    990 	cube->addChild(new IncompleteCubeEmptyObjectCase(m_testCtx, m_context.getRenderContext(), "empty_object", "", IVec2(64, 64)));
    991 }
    992 
    993 } // Functional
    994 } // gles2
    995 } // deqp
    996