/*-------------------------------------------------------------------------
 * 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			(GLuint texture) = 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);

	GLuint texture;
	glGenTextures(1, &texture);
	createTexture(texture);

	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);

	glDeleteTextures(1, &texture);

	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				(GLuint texture) = 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));

	GLuint texture;
	glGenTextures(1, &texture);
	createTexture(texture);

	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;
	}

	glDeleteTextures(1, &texture);

	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			(GLuint texture);

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 (GLuint texture)
{
	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();

	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			(GLuint texture);

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 (GLuint texture)
{
	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(m_format, GL_UNSIGNED_BYTE);
	tcu::TextureLevel	levelData	(fmt);

	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					(GLuint texture);

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 (GLuint texture)
{
	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
	tcu::TextureLevel	levelData	(fmt);

	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				(GLuint texture);

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 (GLuint texture)
{
	TestLog&			log			= m_testCtx.getLog();
	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
	tcu::TextureLevel	levelData	(fmt);

	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				(GLuint texture);

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 (GLuint texture)
{
	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
	tcu::TextureLevel	levelData	(fmt);

	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					(GLuint texture);

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 (GLuint 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			(GLuint texture);

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 (GLuint texture)
{
	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
	tcu::TextureLevel	levelData	(fmt);

	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				(GLuint texture);

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 (GLuint texture)
{
	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
	tcu::TextureLevel	levelData	(fmt);

	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					(GLuint texture);

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 (GLuint texture)
{
	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
	tcu::TextureLevel	levelData	(fmt);

	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				(GLuint texture);

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 (GLuint texture)
{
	TestLog&			log			= m_testCtx.getLog();
	tcu::TextureFormat	fmt			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
	tcu::TextureLevel	levelData	(fmt);

	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				(GLuint texture);

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 (GLuint texture)
{
	tcu::TextureFormat		fmt				= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
	tcu::TextureLevel		levelData		(fmt);

	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				(GLuint texture);

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 (GLuint 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
