/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 2.0 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Texture completeness tests.
 *//*--------------------------------------------------------------------*/

#include "es2fTextureCompletenessTests.hpp"
#include "glsTextureTestUtil.hpp"

#include "tcuTestLog.hpp"
#include "tcuSurface.hpp"
#include "tcuImageCompare.hpp"
#include "tcuVector.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuRenderTarget.hpp"

#include "deRandom.hpp"
#include "deMath.h"
#include "deInt32.h"
#include "deString.h"

#include "gluTextureUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "gluContextInfo.hpp"
#include "gluRenderContext.hpp"

#include "glw.h"

namespace deqp
{
namespace gles2
{
namespace Functional
{

using std::vector;
using std::string;
using tcu::TestLog;
using tcu::TextureFormat;
using tcu::Sampler;
using tcu::IVec2;
using tcu::RGBA;
using gls::TextureTestUtil::TextureRenderer;
using glu::TextureTestUtil::computeQuadTexCoord2D;
using glu::TextureTestUtil::computeQuadTexCoordCube;

static const GLenum s_cubeTargets[] =
{
	GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
	GL_TEXTURE_CUBE_MAP_POSITIVE_X,
	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
	GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
	GL_TEXTURE_CUBE_MAP_POSITIVE_Z
};

static bool isExtensionSupported (const glu::ContextInfo& ctxInfo, const char* extension)
{
	vector<string> extensions = ctxInfo.getExtensions();

	for (vector<string>::iterator iter = extensions.begin(); iter != extensions.end(); ++iter)
		if (iter->compare(extension) == 0)
			return true;

	return false;
}

static bool compareToConstantColor (TestLog& log, const char* imageSetName, const char* imageSetDesc, const tcu::Surface& result, tcu::CompareLogMode logMode, RGBA color)
{
	bool isOk = true;

	for (int y = 0; y < result.getHeight(); y++)
	{
		for (int x = 0; x < result.getWidth(); x++)
		{
			if (result.getPixel(x, y).getRed()		!= color.getRed()	||
				result.getPixel(x, y).getGreen()	!= color.getGreen() ||
				result.getPixel(x, y).getBlue()		!= color.getBlue()	||
				result.getPixel(x, y).getAlpha()	!= color.getAlpha())
			{
				isOk = false;
			}
		}
	}

	if (!isOk || logMode == tcu::COMPARE_LOG_EVERYTHING)
	{
		if (!isOk)
			log << TestLog::Message << "Image comparison failed" << TestLog::EndMessage;

		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result)
			<< TestLog::EndImageSet;
	}
	else if (logMode == tcu::COMPARE_LOG_RESULT)
		log << TestLog::ImageSet(imageSetName, imageSetDesc)
			<< TestLog::Image("Result",		"Result",		result)
			<< TestLog::EndImageSet;

	return isOk;
}

// Base classes.

class Tex2DCompletenessCase : public tcu::TestCase
{
public:
							Tex2DCompletenessCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description);
							~Tex2DCompletenessCase	(void) {};

	IterateResult			iterate					(void);

protected:
	virtual void			createTexture			(void) = 0;

	tcu::TestContext&		m_testCtx;
	glu::RenderContext&		m_renderCtx;
	RGBA					m_compareColor;
};

Tex2DCompletenessCase::Tex2DCompletenessCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description)
	: TestCase			(testCtx, name, description)
	, m_testCtx			(testCtx)
	, m_renderCtx		(renderCtx)
	, m_compareColor	(RGBA(0,0,0,255))
{
}

Tex2DCompletenessCase::IterateResult Tex2DCompletenessCase::iterate (void)
{
	int					viewportWidth	= de::min(64, m_renderCtx.getRenderTarget().getWidth());
	int					viewportHeight	= de::min(64, m_renderCtx.getRenderTarget().getHeight());
	TestLog&			log				= m_testCtx.getLog();
	TextureRenderer		renderer		(m_renderCtx, log, glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP);
	tcu::Surface		renderedFrame	(viewportWidth, viewportHeight);
	vector<float>		texCoord;

	de::Random			random			(deStringHash(getName()));
	int					offsetX			= random.getInt(0, m_renderCtx.getRenderTarget().getWidth()		- viewportWidth	);
	int					offsetY			= random.getInt(0, m_renderCtx.getRenderTarget().getHeight()	- viewportHeight);

	computeQuadTexCoord2D	(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));

	glViewport				(offsetX, offsetY, viewportWidth, viewportHeight);

	createTexture			();
	renderer.renderQuad		(0, &texCoord[0], glu::TextureTestUtil::TEXTURETYPE_2D);
	glu::readPixels			(m_renderCtx, offsetX, offsetY, renderedFrame.getAccess());

	bool isOk = compareToConstantColor(log, "Result", "Image comparison result", renderedFrame, tcu::COMPARE_LOG_RESULT, m_compareColor);

	m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
							isOk ? "Pass"				: "Image comparison failed");
	return STOP;
}

class TexCubeCompletenessCase : public tcu::TestCase
{
public:
							TexCubeCompletenessCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description);
							~TexCubeCompletenessCase	(void) {};

	IterateResult			iterate						(void);

protected:
	virtual void			createTexture				(void) = 0;

	tcu::TestContext&		m_testCtx;
	glu::RenderContext&		m_renderCtx;
	RGBA					m_compareColor;
};

TexCubeCompletenessCase::TexCubeCompletenessCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description)
	: TestCase			(testCtx, name, description)
	, m_testCtx			(testCtx)
	, m_renderCtx		(renderCtx)
	, m_compareColor	(RGBA(0,0,0,255))
{
}

TexCubeCompletenessCase::IterateResult TexCubeCompletenessCase::iterate (void)
{
	int					viewportWidth	= de::min(64, m_renderCtx.getRenderTarget().getWidth());
	int					viewportHeight	= de::min(64, m_renderCtx.getRenderTarget().getHeight());
	bool				allFacesOk		= true;
	TestLog&			log				= m_testCtx.getLog();
	TextureRenderer		renderer		(m_renderCtx, log, glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP);
	tcu::Surface		renderedFrame	(viewportWidth, viewportHeight);
	vector<float>		texCoord;

	de::Random			random			(deStringHash(getName()));
	int					offsetX			= random.getInt(0, de::max(0,m_renderCtx.getRenderTarget().getWidth()	- 64));
	int					offsetY			= random.getInt(0, de::max(0,m_renderCtx.getRenderTarget().getHeight()	- 64));

	createTexture();

	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
	{
		computeQuadTexCoordCube	(texCoord, (tcu::CubeFace)face);

		glViewport				(offsetX, offsetY, viewportWidth, viewportHeight);

		renderer.renderQuad		(0, &texCoord[0], glu::TextureTestUtil::TEXTURETYPE_CUBE);
		glu::readPixels			(m_renderCtx, offsetX, offsetY, renderedFrame.getAccess());

		bool isOk = compareToConstantColor(log, "Result", "Image comparison result", renderedFrame, tcu::COMPARE_LOG_RESULT, m_compareColor);

		if (!isOk)
			allFacesOk = false;
	}

	m_testCtx.setTestResult(allFacesOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
							allFacesOk ? "Pass"					: "Image comparison failed");
	return STOP;
}

// Texture 2D tests.

class Incomplete2DSizeCase : public Tex2DCompletenessCase
{
public:
								Incomplete2DSizeCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx, const glu::ContextInfo& ctxInfo);
								~Incomplete2DSizeCase	(void) {}

	virtual void				createTexture			(void);

private:
	int							m_invalidLevelNdx;
	IVec2						m_invalidLevelSize;
	const glu::ContextInfo&		m_ctxInfo;
	IVec2						m_size;
};

Incomplete2DSizeCase::Incomplete2DSizeCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx, const glu::ContextInfo& ctxInfo)
	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
	, m_invalidLevelNdx			(invalidLevelNdx)
	, m_invalidLevelSize		(invalidLevelSize)
	, m_ctxInfo					(ctxInfo)
	, m_size					(size)
{
}

void Incomplete2DSizeCase::createTexture (void)
{
	static const char* const s_relaxingExtensions[] =
	{
		"GL_OES_texture_npot",
		"GL_NV_texture_npot_2D_mipmap",
	};

	tcu::TextureFormat		fmt				= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
	tcu::TextureLevel		levelData		(fmt);
	TestLog&				log				= m_testCtx.getLog();

	GLuint texture;
	glGenTextures	(1, &texture);
	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
	glBindTexture	(GL_TEXTURE_2D, texture);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);

	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));

	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
	{
		int	levelW = (levelNdx == m_invalidLevelNdx) ? m_invalidLevelSize.x() : de::max(1, m_size.x() >> levelNdx);
		int	levelH = (levelNdx == m_invalidLevelNdx) ? m_invalidLevelSize.y() : de::max(1, m_size.y() >> levelNdx);

		levelData.setSize(m_size.x(), m_size.y());
		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));

		glTexImage2D(GL_TEXTURE_2D, levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
	}

	GLU_CHECK_MSG("Set texturing state");

	// If size not allowed in core, search for relaxing extensions
	if (!deIsPowerOfTwo32(m_size.x()) && !deIsPowerOfTwo32(m_size.y()))
	{
		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_relaxingExtensions); ++ndx)
		{
			if (isExtensionSupported(m_ctxInfo, s_relaxingExtensions[ndx]))
			{
				log << TestLog::Message << s_relaxingExtensions[ndx] << " supported, assuming completeness test to pass." << TestLog::EndMessage;
				m_compareColor = RGBA(0,0,255,255);
				break;
			}
		}
	}
}

class Incomplete2DFormatCase : public Tex2DCompletenessCase
{
public:
							Incomplete2DFormatCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat, int invalidLevelNdx);
							~Incomplete2DFormatCase	(void) {}

	virtual void			createTexture			(void);

private:
	int						m_invalidLevelNdx;
	deUint32				m_format;
	deUint32				m_invalidFormat;
	IVec2					m_size;
};

Incomplete2DFormatCase::Incomplete2DFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat, int invalidLevelNdx)
	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
	, m_invalidLevelNdx			(invalidLevelNdx)
	, m_format					(format)
	, m_invalidFormat			(invalidFormat)
	, m_size					(size)
{
}

void Incomplete2DFormatCase::createTexture (void)
{
	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(m_format, GL_UNSIGNED_BYTE);
	tcu::TextureLevel	levelData	(fmt);

	GLuint texture;
	glGenTextures	(1, &texture);
	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
	glBindTexture	(GL_TEXTURE_2D, texture);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);

	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));

	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
	{
		int	levelW = de::max(1, m_size.x() >> levelNdx);
		int	levelH = de::max(1, m_size.y() >> levelNdx);

		levelData.setSize(m_size.x(), m_size.y());
		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));

		deUint32 format = levelNdx == m_invalidLevelNdx ? m_invalidFormat : m_format;

		glTexImage2D(GL_TEXTURE_2D, levelNdx, format, levelW, levelH, 0, format, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
	}

	GLU_CHECK_MSG("Set texturing state");
}

class Incomplete2DMissingLevelCase : public Tex2DCompletenessCase
{
public:
						Incomplete2DMissingLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int missingLevelNdx);
						~Incomplete2DMissingLevelCase	(void) {}

	virtual void		createTexture					(void);

private:
	int					m_missingLevelNdx;
	IVec2				m_size;
};

Incomplete2DMissingLevelCase::Incomplete2DMissingLevelCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int missingLevelNdx)
	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
	, m_missingLevelNdx			(missingLevelNdx)
	, m_size					(size)
{
}

void Incomplete2DMissingLevelCase::createTexture (void)
{
	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
	tcu::TextureLevel	levelData	(fmt);

	GLuint texture;
	glGenTextures	(1, &texture);
	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
	glBindTexture	(GL_TEXTURE_2D, texture);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);

	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));

	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
	{
		levelData.setSize(m_size.x(), m_size.y());
		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));

		int	levelW = de::max(1, m_size.x() >> levelNdx);
		int	levelH = de::max(1, m_size.y() >> levelNdx);

		// Skip specified level.
		if (levelNdx != m_missingLevelNdx)
			glTexImage2D(GL_TEXTURE_2D, levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
	}

	GLU_CHECK_MSG("Set texturing state");
}

class Incomplete2DWrapModeCase : public Tex2DCompletenessCase
{
public:
								Incomplete2DWrapModeCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 wrapT, deUint32 wrapS, const glu::ContextInfo& ctxInfo);
								~Incomplete2DWrapModeCase	(void) {}

	virtual void				createTexture				(void);

private:
	deUint32					m_wrapT;
	deUint32					m_wrapS;
	const glu::ContextInfo&		m_ctxInfo;
	IVec2						m_size;
};

Incomplete2DWrapModeCase::Incomplete2DWrapModeCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 wrapT, deUint32 wrapS, const glu::ContextInfo& ctxInfo)
	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
	, m_wrapT					(wrapT)
	, m_wrapS					(wrapS)
	, m_ctxInfo					(ctxInfo)
	, m_size					(size)
{
}

void Incomplete2DWrapModeCase::createTexture (void)
{
	TestLog&			log			= m_testCtx.getLog();
	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
	tcu::TextureLevel	levelData	(fmt);

	GLuint texture;
	glGenTextures(1, &texture);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glBindTexture(GL_TEXTURE_2D, texture);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);

	levelData.setSize(m_size.x(), m_size.y());
	clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));

	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_size.x(), m_size.y(), 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());

	GLU_CHECK_MSG("Set texturing state");

	const char* extension = "GL_OES_texture_npot";
	if (isExtensionSupported(m_ctxInfo, extension))
	{
		log << TestLog::Message << extension << " supported, assuming completeness test to pass." << TestLog::EndMessage;
		m_compareColor = RGBA(0,0,255,255);
	}
}

class Complete2DExtraLevelCase : public Tex2DCompletenessCase
{
public:
						Complete2DExtraLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size);
						~Complete2DExtraLevelCase	(void) {}

	virtual void		createTexture				(void);

private:
	IVec2				m_size;
};

Complete2DExtraLevelCase::Complete2DExtraLevelCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size)
	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
	, m_size					(size)
{
}

void Complete2DExtraLevelCase::createTexture (void)
{
	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
	tcu::TextureLevel	levelData	(fmt);

	GLuint texture;
	glGenTextures	(1, &texture);
	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
	glBindTexture	(GL_TEXTURE_2D, texture);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);

	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));

	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
	{
		int	levelW = de::max(1, m_size.x() >> levelNdx);
		int	levelH = de::max(1, m_size.y() >> levelNdx);

		levelData.setSize(m_size.x(), m_size.y());
		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));

		glTexImage2D(GL_TEXTURE_2D, levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
	}

	// Specify extra level.
	glTexImage2D(GL_TEXTURE_2D, numLevels+1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
	m_compareColor = RGBA(0,0,255,255);

	GLU_CHECK_MSG("Set texturing state");
}

class Incomplete2DEmptyObjectCase : public Tex2DCompletenessCase
{
public:
						Incomplete2DEmptyObjectCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size);
						~Incomplete2DEmptyObjectCase	(void) {}

	virtual void		createTexture					(void);

private:
	IVec2				m_size;
};

Incomplete2DEmptyObjectCase::Incomplete2DEmptyObjectCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size)
	: Tex2DCompletenessCase		(testCtx, renderCtx, name, description)
	, m_size					(size)
{
}

void Incomplete2DEmptyObjectCase::createTexture (void)
{
	GLuint texture;
	glGenTextures	(1, &texture);
	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
	glBindTexture	(GL_TEXTURE_2D, texture);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);

	GLU_CHECK_MSG("Set texturing state");
}

// Cube texture tests.

class IncompleteCubeSizeCase : public TexCubeCompletenessCase
{
public:
							IncompleteCubeSizeCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx);
							IncompleteCubeSizeCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx, tcu::CubeFace invalidCubeFace);
							~IncompleteCubeSizeCase	(void) {}

	virtual void			createTexture			(void);

private:
	int						m_invalidLevelNdx;
	IVec2					m_invalidLevelSize;
	tcu::CubeFace			m_invalidCubeFace;
	IVec2					m_size;
};

IncompleteCubeSizeCase::IncompleteCubeSizeCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx)
	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
	, m_invalidLevelNdx				(invalidLevelNdx)
	, m_invalidLevelSize			(invalidLevelSize)
	, m_invalidCubeFace				(tcu::CUBEFACE_LAST)
	, m_size						(size)
{
}

IncompleteCubeSizeCase::IncompleteCubeSizeCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, IVec2 invalidLevelSize, int invalidLevelNdx, tcu::CubeFace invalidCubeFace)
	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
	, m_invalidLevelNdx				(invalidLevelNdx)
	, m_invalidLevelSize			(invalidLevelSize)
	, m_invalidCubeFace				(invalidCubeFace)
	, m_size						(size)
{
}

void IncompleteCubeSizeCase::createTexture (void)
{
	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
	tcu::TextureLevel	levelData	(fmt);

	GLuint texture;
	glGenTextures	(1, &texture);
	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
	glBindTexture	(GL_TEXTURE_CUBE_MAP, texture);

	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		GL_REPEAT);
	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		GL_REPEAT);
	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);

	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));

	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
	{
		levelData.setSize(m_size.x(), m_size.y());
		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));

		for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
		{
			int levelW = de::max(1, m_size.x() >> levelNdx);
			int levelH = de::max(1, m_size.y() >> levelNdx);
			if (levelNdx == m_invalidLevelNdx && (m_invalidCubeFace == tcu::CUBEFACE_LAST || m_invalidCubeFace == targetNdx))
			{
				levelW =  m_invalidLevelSize.x();
				levelH =  m_invalidLevelSize.y();
			}
			glTexImage2D(s_cubeTargets[targetNdx], levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
		}
	}

	GLU_CHECK_MSG("Set texturing state");
}

class IncompleteCubeFormatCase : public TexCubeCompletenessCase
{
public:
							IncompleteCubeFormatCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat);
							IncompleteCubeFormatCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat, tcu::CubeFace invalidCubeFace);
							~IncompleteCubeFormatCase	(void) {}

	virtual void			createTexture				(void);

private:
	deUint32				m_format;
	deUint32				m_invalidFormat;
	tcu::CubeFace			m_invalidCubeFace;
	IVec2					m_size;
};

IncompleteCubeFormatCase::IncompleteCubeFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat)
	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
	, m_format						(format)
	, m_invalidFormat				(invalidFormat)
	, m_invalidCubeFace				(tcu::CUBEFACE_LAST)
	, m_size						(size)
{
}

IncompleteCubeFormatCase::IncompleteCubeFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 format, deUint32 invalidFormat, tcu::CubeFace invalidCubeFace)
	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
	, m_format						(format)
	, m_invalidFormat				(invalidFormat)
	, m_invalidCubeFace				(invalidCubeFace)
	, m_size						(size)
{
}

void IncompleteCubeFormatCase::createTexture (void)
{
	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
	tcu::TextureLevel	levelData	(fmt);

	GLuint texture;
	glGenTextures	(1, &texture);
	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
	glBindTexture	(GL_TEXTURE_CUBE_MAP, texture);

	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		GL_REPEAT);
	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		GL_REPEAT);
	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);

	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));

	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
	{
		levelData.setSize(m_size.x(), m_size.y());
		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));

		int	levelW = de::max(1, m_size.x() >> levelNdx);
		int	levelH = de::max(1, m_size.y() >> levelNdx);

		for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
		{
			deUint32 format = m_format;
			if (levelNdx == 0 && (m_invalidCubeFace == tcu::CUBEFACE_LAST || m_invalidCubeFace == targetNdx))
				format = m_invalidFormat;

			glTexImage2D(s_cubeTargets[targetNdx], levelNdx, format, levelW, levelH, 0, format, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
		}
	}

	GLU_CHECK_MSG("Set texturing state");
}

class IncompleteCubeMissingLevelCase : public TexCubeCompletenessCase
{
public:
							IncompleteCubeMissingLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int invalidLevelNdx);
							IncompleteCubeMissingLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int invalidLevelNdx, tcu::CubeFace invalidCubeFace);
							~IncompleteCubeMissingLevelCase	(void) {}

	virtual void			createTexture					(void);

private:
	int						m_invalidLevelNdx;
	tcu::CubeFace			m_invalidCubeFace;
	IVec2					m_size;
};

IncompleteCubeMissingLevelCase::IncompleteCubeMissingLevelCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int invalidLevelNdx)
	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
	, m_invalidLevelNdx				(invalidLevelNdx)
	, m_invalidCubeFace				(tcu::CUBEFACE_LAST)
	, m_size						(size)
{
}

IncompleteCubeMissingLevelCase::IncompleteCubeMissingLevelCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, int invalidLevelNdx, tcu::CubeFace invalidCubeFace)
	: TexCubeCompletenessCase		(testCtx, renderCtx, name, description)
	, m_invalidLevelNdx				(invalidLevelNdx)
	, m_invalidCubeFace				(invalidCubeFace)
	, m_size						(size)
{
}

void IncompleteCubeMissingLevelCase::createTexture (void)
{
	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
	tcu::TextureLevel	levelData	(fmt);

	GLuint texture;
	glGenTextures	(1, &texture);
	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
	glBindTexture	(GL_TEXTURE_CUBE_MAP, texture);

	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		GL_REPEAT);
	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		GL_REPEAT);
	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
	glTexParameteri	(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);

	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));

	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
	{
		levelData.setSize(m_size.x(), m_size.y());
		clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));

		int	levelW = (levelNdx == m_invalidLevelNdx) ? m_size.x() : de::max(1, m_size.x() >> levelNdx);
		int	levelH = (levelNdx == m_invalidLevelNdx) ? m_size.y() : de::max(1, m_size.y() >> levelNdx);

		if (levelNdx != m_invalidLevelNdx || m_invalidCubeFace != tcu::CUBEFACE_LAST)
		{
			for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
			{
				// If single cubeface is specified then skip only that one.
				if (m_invalidCubeFace != targetNdx)
					glTexImage2D(s_cubeTargets[targetNdx], levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
			}
		}
	}

	GLU_CHECK_MSG("Set texturing state");
}

class IncompleteCubeWrapModeCase : public TexCubeCompletenessCase
{
public:
								IncompleteCubeWrapModeCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 wrapT, deUint32 wrapS, const glu::ContextInfo& ctxInfo);
								~IncompleteCubeWrapModeCase	(void) {}

	virtual void				createTexture				(void);

private:
	deUint32					m_wrapT;
	deUint32					m_wrapS;
	const glu::ContextInfo&		m_ctxInfo;
	IVec2						m_size;
};

IncompleteCubeWrapModeCase::IncompleteCubeWrapModeCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size, deUint32 wrapT, deUint32 wrapS, const glu::ContextInfo& ctxInfo)
	: TexCubeCompletenessCase	(testCtx, renderCtx, name, description)
	, m_wrapT					(wrapT)
	, m_wrapS					(wrapS)
	, m_ctxInfo					(ctxInfo)
	, m_size					(size)
{
}

void IncompleteCubeWrapModeCase::createTexture (void)
{
	TestLog&			log			= m_testCtx.getLog();
	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
	tcu::TextureLevel	levelData	(fmt);

	GLuint texture;
	glGenTextures(1, &texture);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glBindTexture(GL_TEXTURE_2D, texture);

	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		m_wrapS);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		m_wrapT);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);

	levelData.setSize(m_size.x(), m_size.y());
	clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));

	for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
		glTexImage2D(s_cubeTargets[targetNdx], 0, GL_RGBA, m_size.x(), m_size.y(), 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());

	GLU_CHECK_MSG("Set texturing state");

	const char* extension = "GL_OES_texture_npot";
	if (isExtensionSupported(m_ctxInfo, extension))
	{
		log << TestLog::Message << extension << " supported, assuming completeness test to pass." << TestLog::EndMessage;
		m_compareColor = RGBA(0,0,255,255);
	}
}

class CompleteCubeExtraLevelCase : public TexCubeCompletenessCase
{
public:
						CompleteCubeExtraLevelCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size);
						~CompleteCubeExtraLevelCase	(void) {}

	virtual void		createTexture				(void);

private:
	IVec2				m_size;
};

CompleteCubeExtraLevelCase::CompleteCubeExtraLevelCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size)
	: TexCubeCompletenessCase	(testCtx, renderCtx, name, description)
	, m_size					(size)
{
}

void CompleteCubeExtraLevelCase::createTexture (void)
{
	tcu::TextureFormat		fmt				= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
	tcu::TextureLevel		levelData		(fmt);

	GLuint texture;
	glGenTextures	(1, &texture);
	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
	glBindTexture	(GL_TEXTURE_2D, texture);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);

	int numLevels = 1 + de::max(deLog2Floor32(m_size.x()), deLog2Floor32(m_size.y()));

	levelData.setSize(m_size.x(), m_size.y());
	clear(levelData.getAccess(), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));

	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
	{
		int	levelW = de::max(1, m_size.x() >> levelNdx);
		int	levelH = de::max(1, m_size.y() >> levelNdx);

		for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
			glTexImage2D(s_cubeTargets[targetNdx], levelNdx, GL_RGBA, levelW, levelH, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());
	}

	// Specify extra level.
	for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(s_cubeTargets); targetNdx++)
		glTexImage2D(s_cubeTargets[targetNdx], numLevels+1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, levelData.getAccess().getDataPtr());

	m_compareColor = RGBA(0,0,255,255);

	GLU_CHECK_MSG("Set texturing state");
}

class IncompleteCubeEmptyObjectCase : public TexCubeCompletenessCase
{
public:
							IncompleteCubeEmptyObjectCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size);
							~IncompleteCubeEmptyObjectCase	(void) {}

	virtual void			createTexture				(void);

private:
	IVec2					m_size;
};

IncompleteCubeEmptyObjectCase::IncompleteCubeEmptyObjectCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, IVec2 size)
	: TexCubeCompletenessCase	(testCtx, renderCtx, name, description)
	, m_size					(size)
{
}

void IncompleteCubeEmptyObjectCase::createTexture (void)
{
	GLuint texture;
	glGenTextures	(1, &texture);
	glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);
	glBindTexture	(GL_TEXTURE_2D, texture);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);

	GLU_CHECK_MSG("Set texturing state");
}

// Texture completeness group.

TextureCompletenessTests::TextureCompletenessTests (Context& context)
	: TestCaseGroup(context, "completeness", "Completeness tests")
{
}

void TextureCompletenessTests::init (void)
{
	tcu::TestCaseGroup* tex2d = new tcu::TestCaseGroup(m_testCtx, "2d", "2D completeness");
	addChild(tex2d);
	tcu::TestCaseGroup* cube = new tcu::TestCaseGroup(m_testCtx, "cube", "Cubemap completeness");
	addChild(cube);

	// Texture 2D size.
	tex2d->addChild(new Incomplete2DSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size",				"", IVec2(255, 255), IVec2(255, 255), 0, m_context.getContextInfo()));
	tex2d->addChild(new Incomplete2DSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_0",		"", IVec2(256, 256), IVec2(255, 255), 0, m_context.getContextInfo()));
	tex2d->addChild(new Incomplete2DSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_1",		"", IVec2(256, 256), IVec2(127, 127), 1, m_context.getContextInfo()));
	tex2d->addChild(new Incomplete2DSizeCase(m_testCtx, m_context.getRenderContext(), "not_positive_level_0",	"", IVec2(256, 256), IVec2(0, 0),	  0, m_context.getContextInfo()));
	// Texture 2D format.
	tex2d->addChild(new Incomplete2DFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgb_rgba",						"", IVec2(128, 128), GL_RGB,				GL_RGBA,			1));
	tex2d->addChild(new Incomplete2DFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgba_rgb",						"", IVec2(128, 128), GL_RGBA,				GL_RGB,				1));
	tex2d->addChild(new Incomplete2DFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_luminance_luminance_alpha",	"", IVec2(128, 128), GL_LUMINANCE,			GL_LUMINANCE_ALPHA,	1));
	tex2d->addChild(new Incomplete2DFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_luminance_alpha_luminance",	"", IVec2(128, 128), GL_LUMINANCE_ALPHA,	GL_LUMINANCE,		1));
	// Texture 2D missing level.
	tex2d->addChild(new Incomplete2DMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_1",			"", IVec2(128, 128),	1));
	tex2d->addChild(new Incomplete2DMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_3",			"", IVec2(128, 128),	3));
	tex2d->addChild(new Incomplete2DMissingLevelCase(m_testCtx, m_context.getRenderContext(), "last_level_missing",			"", IVec2(128, 64),		de::max(deLog2Floor32(128), deLog2Floor32(64))));
	// Texture 2D wrap modes.
	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_t_repeat",			"", IVec2(127, 127), GL_CLAMP_TO_EDGE,		GL_REPEAT,				m_context.getContextInfo()));
	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_s_repeat",			"", IVec2(127, 127), GL_REPEAT,				GL_CLAMP_TO_EDGE,		m_context.getContextInfo()));
	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_all_repeat",		"", IVec2(127, 127), GL_REPEAT,				GL_REPEAT,				m_context.getContextInfo()));
	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_mirrored_repeat",	"", IVec2(127, 127), GL_MIRRORED_REPEAT,	GL_MIRRORED_REPEAT,		m_context.getContextInfo()));
	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "repeat_width_npot",		"", IVec2(127, 128), GL_REPEAT,				GL_REPEAT,				m_context.getContextInfo()));
	tex2d->addChild(new Incomplete2DWrapModeCase(m_testCtx, m_context.getRenderContext(), "repeat_height_npot",		"", IVec2(128, 127), GL_REPEAT,				GL_REPEAT,				m_context.getContextInfo()));
	// Texture 2D extra level.
	tex2d->addChild(new Complete2DExtraLevelCase(m_testCtx, m_context.getRenderContext(), "extra_level", "", IVec2(64, 64)));
	// Texture 2D empty object.
	tex2d->addChild(new Incomplete2DEmptyObjectCase(m_testCtx, m_context.getRenderContext(), "empty_object", "", IVec2(64, 64)));

	// Cube size.
	cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_0",			"", IVec2(64, 64), IVec2(63, 63), 0));
	cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "npot_size_level_1",			"", IVec2(64, 64), IVec2(31, 31), 1));
	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));
	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));
	cube->addChild(new IncompleteCubeSizeCase(m_testCtx, m_context.getRenderContext(), "not_positive_level_0",		"", IVec2(64, 64), IVec2(0,0)	, 0));
	// Cube format.
	cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgb_rgba_level_0",					"", IVec2(64, 64), GL_RGB,				GL_RGBA));
	cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_rgba_rgb_level_0",					"", IVec2(64, 64), GL_RGBA,				GL_RGB));
	cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_luminance_luminance_alpha_level_0",	"", IVec2(64, 64), GL_LUMINANCE,		GL_LUMINANCE_ALPHA));
	cube->addChild(new IncompleteCubeFormatCase(m_testCtx, m_context.getRenderContext(), "format_mismatch_luminance_alpha_luminance_level_0",	"", IVec2(64, 64), GL_LUMINANCE_ALPHA,	GL_LUMINANCE));
	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));
	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));
	// Cube missing level.
	cube->addChild(new IncompleteCubeMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_1",		"", IVec2(64, 64), 1));
	cube->addChild(new IncompleteCubeMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_3",		"", IVec2(64, 64), 3));
	cube->addChild(new IncompleteCubeMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_1_pos_y",	"", IVec2(64, 64), 1, tcu::CUBEFACE_POSITIVE_Y));
	cube->addChild(new IncompleteCubeMissingLevelCase(m_testCtx, m_context.getRenderContext(), "missing_level_3_neg_y",	"", IVec2(64, 64), 3, tcu::CUBEFACE_NEGATIVE_Y));
	// Cube wrap modes.
	cube->addChild(new IncompleteCubeWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_t_repeat",			"", IVec2(127, 127), GL_CLAMP_TO_EDGE,		GL_REPEAT,				m_context.getContextInfo()));
	cube->addChild(new IncompleteCubeWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_s_repeat",			"", IVec2(127, 127), GL_REPEAT,				GL_CLAMP_TO_EDGE,		m_context.getContextInfo()));
	cube->addChild(new IncompleteCubeWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_all_repeat",		"", IVec2(127, 127), GL_REPEAT,				GL_REPEAT,				m_context.getContextInfo()));
	cube->addChild(new IncompleteCubeWrapModeCase(m_testCtx, m_context.getRenderContext(), "npot_mirrored_repeat",	"", IVec2(127, 127), GL_MIRRORED_REPEAT,	GL_MIRRORED_REPEAT,		m_context.getContextInfo()));
	// Cube extra level.
	cube->addChild(new CompleteCubeExtraLevelCase(m_testCtx, m_context.getRenderContext(), "extra_level", "", IVec2(64, 64)));
	// Cube extra level.
	cube->addChild(new IncompleteCubeEmptyObjectCase(m_testCtx, m_context.getRenderContext(), "empty_object", "", IVec2(64, 64)));
}

} // Functional
} // gles2
} // deqp
