/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.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 format tests.
 *
 * Constants:
 *  + nearest-neighbor filtering
 *  + no mipmaps
 *  + full texture coordinate range (but not outside) tested
 *  + accessed from fragment shader
 *  + texture unit 0
 *  + named texture object
 *
 * Variables:
 *  + texture format
 *  + texture type: 2D or cubemap
 *//*--------------------------------------------------------------------*/

#include "es3fTextureFormatTests.hpp"
#include "gluPixelTransfer.hpp"
#include "gluStrUtil.hpp"
#include "gluTexture.hpp"
#include "gluTextureUtil.hpp"
#include "glsTextureTestUtil.hpp"
#include "tcuTextureUtil.hpp"
#include "deStringUtil.hpp"
#include "deRandom.hpp"
#include "glwEnums.hpp"
#include "glwFunctions.hpp"
#include "gluContextInfo.hpp"
#include "deUniquePtr.hpp"

using std::vector;
using std::string;
using tcu::TestLog;

using de::MovePtr;
using glu::ContextInfo;

namespace deqp
{
namespace gles3
{
namespace Functional
{

using namespace deqp::gls;
using namespace deqp::gls::TextureTestUtil;
using namespace glu::TextureTestUtil;
using tcu::Sampler;

namespace
{

void checkSupport (const glu::ContextInfo& info, deUint32 internalFormat)
{
	if (internalFormat == GL_SR8_EXT && !info.isExtensionSupported("GL_EXT_texture_sRGB_R8"))
		TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_R8 is not supported.");

	if (internalFormat == GL_SRG8_EXT && !info.isExtensionSupported("GL_EXT_texture_sRGB_RG8"))
		TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_RG8 is not supported.");
}

} // anonymous

// Texture2DFormatCase

class Texture2DFormatCase : public tcu::TestCase
{
public:
							Texture2DFormatCase		(tcu::TestContext& testCtx, Context& context, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height);
							Texture2DFormatCase		(tcu::TestContext& testCtx, Context& context, const char* name, const char* description, deUint32 internalFormat, int width, int height);
							~Texture2DFormatCase	(void);

	void					init					(void);
	void					deinit					(void);
	IterateResult			iterate					(void);

private:
							Texture2DFormatCase		(const Texture2DFormatCase& other);
	Texture2DFormatCase&	operator=				(const Texture2DFormatCase& other);

	glu::RenderContext&		m_renderCtx;
	const glu::ContextInfo&	m_renderCtxInfo;

	deUint32				m_format;
	deUint32				m_dataType;
	int						m_width;
	int						m_height;

	glu::Texture2D*			m_texture;
	TextureRenderer			m_renderer;
};

Texture2DFormatCase::Texture2DFormatCase (tcu::TestContext& testCtx, Context& context, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height)
	: TestCase			(testCtx, name, description)
	, m_renderCtx		(context.getRenderContext())
	, m_renderCtxInfo	(context.getContextInfo())
	, m_format			(format)
	, m_dataType		(dataType)
	, m_width			(width)
	, m_height			(height)
	, m_texture			(DE_NULL)
	, m_renderer		(context.getRenderContext(), testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
{
}

Texture2DFormatCase::Texture2DFormatCase (tcu::TestContext& testCtx,  Context& context, const char* name, const char* description, deUint32 internalFormat, int width, int height)
	: TestCase			(testCtx, name, description)
	, m_renderCtx		(context.getRenderContext())
	, m_renderCtxInfo	(context.getContextInfo())
	, m_format			(internalFormat)
	, m_dataType		(GL_NONE)
	, m_width			(width)
	, m_height			(height)
	, m_texture			(DE_NULL)
	, m_renderer		(context.getRenderContext(), testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
{
}

Texture2DFormatCase::~Texture2DFormatCase (void)
{
	deinit();
}

void Texture2DFormatCase::init (void)
{
	checkSupport(m_renderCtxInfo, m_format);

	TestLog&				log		= m_testCtx.getLog();
	tcu::TextureFormat		fmt		= m_dataType ? glu::mapGLTransferFormat(m_format, m_dataType) : glu::mapGLInternalFormat(m_format);
	tcu::TextureFormatInfo	spec	= tcu::getTextureFormatInfo(fmt);
	std::ostringstream		fmtName;

	if (m_dataType)
		fmtName << glu::getTextureFormatStr(m_format) << ", " << glu::getTypeStr(m_dataType);
	else
		fmtName << glu::getTextureFormatStr(m_format);

	log << TestLog::Message << "2D texture, " << fmtName.str() << ", " << m_width << "x" << m_height
							<< ",\n  fill with " << formatGradient(&spec.valueMin, &spec.valueMax) << " gradient"
		<< TestLog::EndMessage;

	m_texture = m_dataType != GL_NONE
			  ? new glu::Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height)	// Implicit internal format.
			  : new glu::Texture2D(m_renderCtx, m_format, m_width, m_height);				// Explicit internal format.

	// Fill level 0.
	m_texture->getRefTexture().allocLevel(0);
	tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), spec.valueMin, spec.valueMax);
}

void Texture2DFormatCase::deinit (void)
{
	delete m_texture;
	m_texture = DE_NULL;

	m_renderer.clear();
}

Texture2DFormatCase::IterateResult Texture2DFormatCase::iterate (void)
{
	TestLog&				log					= m_testCtx.getLog();
	const glw::Functions&	gl					= m_renderCtx.getFunctions();
	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_width, m_height, deStringHash(getName()));
	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
	vector<float>			texCoord;
	ReferenceParams			renderParams		(TEXTURETYPE_2D);
	tcu::TextureFormatInfo	spec				= tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
	const deUint32			wrapS				= GL_CLAMP_TO_EDGE;
	const deUint32			wrapT				= GL_CLAMP_TO_EDGE;
	const deUint32			minFilter			= GL_NEAREST;
	const deUint32			magFilter			= GL_NEAREST;

	renderParams.flags			|= RenderParams::LOG_ALL;
	renderParams.samplerType	= getSamplerType(m_texture->getRefTexture().getFormat());
	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
	renderParams.colorScale		= spec.lookupScale;
	renderParams.colorBias		= spec.lookupBias;

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

	log << TestLog::Message << "Texture parameters:"
							<< "\n  WRAP_S = " << glu::getTextureParameterValueStr(GL_TEXTURE_WRAP_S, wrapS)
							<< "\n  WRAP_T = " << glu::getTextureParameterValueStr(GL_TEXTURE_WRAP_T, wrapT)
							<< "\n  MIN_FILTER = " << glu::getTextureParameterValueStr(GL_TEXTURE_MIN_FILTER, minFilter)
							<< "\n  MAG_FILTER = " << glu::getTextureParameterValueStr(GL_TEXTURE_MAG_FILTER, magFilter)
		<< TestLog::EndMessage;

	// Setup base viewport.
	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

	// Upload texture data to GL.
	m_texture->upload();

	// Bind to unit 0.
	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());

	// Setup nearest neighbor filtering and clamp-to-edge.
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");

	// Draw.
	m_renderer.renderQuad(0, &texCoord[0], renderParams);
	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");

	// Compute reference.
	sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], renderParams);

	// Compare and log.
	bool isOk = compareImages(log, referenceFrame, renderedFrame, threshold);

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

	return STOP;
}

// TextureCubeFormatCase

class TextureCubeFormatCase : public tcu::TestCase
{
public:
							TextureCubeFormatCase	(tcu::TestContext& testCtx, Context& context, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height);
							TextureCubeFormatCase	(tcu::TestContext& testCtx, Context& context, const char* name, const char* description, deUint32 internalFormat, int width, int height);
							~TextureCubeFormatCase	(void);

	void					init					(void);
	void					deinit					(void);
	IterateResult			iterate					(void);

private:
							TextureCubeFormatCase	(const TextureCubeFormatCase& other);
	TextureCubeFormatCase&	operator=				(const TextureCubeFormatCase& other);

	bool					testFace				(tcu::CubeFace face);

	glu::RenderContext&		m_renderCtx;
	const glu::ContextInfo&	m_renderCtxInfo;

	deUint32				m_format;
	deUint32				m_dataType;
	int						m_width;
	int						m_height;

	glu::TextureCube*		m_texture;
	TextureRenderer			m_renderer;

	int						m_curFace;
	bool					m_isOk;
};

TextureCubeFormatCase::TextureCubeFormatCase (tcu::TestContext& testCtx, Context& context, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height)
	: TestCase			(testCtx, name, description)
	, m_renderCtx		(context.getRenderContext())
	, m_renderCtxInfo	(context.getContextInfo())
	, m_format			(format)
	, m_dataType		(dataType)
	, m_width			(width)
	, m_height			(height)
	, m_texture			(DE_NULL)
	, m_renderer		(context.getRenderContext(), testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
	, m_curFace			(0)
	, m_isOk			(false)
{
}

TextureCubeFormatCase::TextureCubeFormatCase (tcu::TestContext& testCtx, Context& context, const char* name, const char* description, deUint32 internalFormat, int width, int height)
	: TestCase			(testCtx, name, description)
	, m_renderCtx		(context.getRenderContext())
	, m_renderCtxInfo	(context.getContextInfo())
	, m_format			(internalFormat)
	, m_dataType		(GL_NONE)
	, m_width			(width)
	, m_height			(height)
	, m_texture			(DE_NULL)
	, m_renderer		(context.getRenderContext(), testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
	, m_curFace			(0)
	, m_isOk			(false)
{
}

TextureCubeFormatCase::~TextureCubeFormatCase (void)
{
	deinit();
}

void TextureCubeFormatCase::init (void)
{
	checkSupport(m_renderCtxInfo, m_format);

	TestLog&				log		= m_testCtx.getLog();
	tcu::TextureFormat		fmt		= m_dataType ? glu::mapGLTransferFormat(m_format, m_dataType) : glu::mapGLInternalFormat(m_format);
	tcu::TextureFormatInfo	spec	= tcu::getTextureFormatInfo(fmt);
	std::ostringstream		fmtName;

	if (m_dataType)
		fmtName << glu::getTextureFormatStr(m_format) << ", " << glu::getTypeStr(m_dataType);
	else
		fmtName << glu::getTextureFormatStr(m_format);

	log << TestLog::Message << "Cube map texture, " << fmtName.str() << ", " << m_width << "x" << m_height
							<< ",\n  fill with " << formatGradient(&spec.valueMin, &spec.valueMax) << " gradient"
		<< TestLog::EndMessage;

	DE_ASSERT(m_width == m_height);
	m_texture = m_dataType != GL_NONE
			  ? new glu::TextureCube(m_renderCtx, m_format, m_dataType, m_width)	// Implicit internal format.
		      : new glu::TextureCube(m_renderCtx, m_format, m_width);				// Explicit internal format.

	// Fill level 0.
	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
	{
		tcu::Vec4 gMin, gMax;

		switch (face)
		{
			case 0: gMin = spec.valueMin.swizzle(0, 1, 2, 3); gMax = spec.valueMax.swizzle(0, 1, 2, 3); break;
			case 1: gMin = spec.valueMin.swizzle(2, 1, 0, 3); gMax = spec.valueMax.swizzle(2, 1, 0, 3); break;
			case 2: gMin = spec.valueMin.swizzle(1, 2, 0, 3); gMax = spec.valueMax.swizzle(1, 2, 0, 3); break;
			case 3: gMin = spec.valueMax.swizzle(0, 1, 2, 3); gMax = spec.valueMin.swizzle(0, 1, 2, 3); break;
			case 4: gMin = spec.valueMax.swizzle(2, 1, 0, 3); gMax = spec.valueMin.swizzle(2, 1, 0, 3); break;
			case 5: gMin = spec.valueMax.swizzle(1, 2, 0, 3); gMax = spec.valueMin.swizzle(1, 2, 0, 3); break;
			default:
				DE_ASSERT(false);
		}

		m_texture->getRefTexture().allocLevel((tcu::CubeFace)face, 0);
		tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevelFace(0, (tcu::CubeFace)face), gMin, gMax);
	}

	// Upload texture data to GL.
	m_texture->upload();

	// Initialize iteration state.
	m_curFace	= 0;
	m_isOk		= true;
}

void TextureCubeFormatCase::deinit (void)
{
	delete m_texture;
	m_texture = DE_NULL;

	m_renderer.clear();
}

bool TextureCubeFormatCase::testFace (tcu::CubeFace face)
{
	TestLog&				log					= m_testCtx.getLog();
	const glw::Functions&	gl					= m_renderCtx.getFunctions();
	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_width, m_height, deStringHash(getName())+(deUint32)face);
	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
	vector<float>			texCoord;
	ReferenceParams			renderParams		(TEXTURETYPE_CUBE);
	tcu::TextureFormatInfo	spec				= tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());

	renderParams.samplerType				= getSamplerType(m_texture->getRefTexture().getFormat());
	renderParams.sampler					= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
	renderParams.sampler.seamlessCubeMap	= true;
	renderParams.colorScale					= spec.lookupScale;
	renderParams.colorBias					= spec.lookupBias;

	// Log render info on first face.
	if (face == tcu::CUBEFACE_NEGATIVE_X)
		renderParams.flags |= RenderParams::LOG_ALL;

	computeQuadTexCoordCube(texCoord, face);

	// \todo [2011-10-28 pyry] Image set name / section?
	log << TestLog::Message << face << TestLog::EndMessage;

	// Setup base viewport.
	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

	// Bind to unit 0.
	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());

	// Setup nearest neighbor filtering and clamp-to-edge.
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");

	m_renderer.renderQuad(0, &texCoord[0], renderParams);
	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");

	// Compute reference.
	sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], renderParams);

	// Compare and log.
	return compareImages(log, referenceFrame, renderedFrame, threshold);
}

TextureCubeFormatCase::IterateResult TextureCubeFormatCase::iterate (void)
{
	// Execute test for all faces.
	if (!testFace((tcu::CubeFace)m_curFace))
		m_isOk = false;

	m_curFace += 1;

	if (m_curFace == tcu::CUBEFACE_LAST)
	{
		m_testCtx.setTestResult(m_isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
								m_isOk ? "Pass"					: "Image comparison failed");
		return STOP;
	}
	else
		return CONTINUE;
}

// Texture2DArrayFormatCase

class Texture2DArrayFormatCase : public tcu::TestCase
{
public:
										Texture2DArrayFormatCase	(tcu::TestContext& testCtx, Context& context, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height, int numLayers);
										Texture2DArrayFormatCase	(tcu::TestContext& testCtx, Context& context, const char* name, const char* description, deUint32 internalFormat, int width, int height, int numLayers);
										~Texture2DArrayFormatCase	(void);

	void								init						(void);
	void								deinit						(void);
	IterateResult						iterate						(void);

private:
										Texture2DArrayFormatCase	(const Texture2DArrayFormatCase& other);
	Texture2DArrayFormatCase&			operator=					(const Texture2DArrayFormatCase& other);

	bool								testLayer					(int layerNdx);

	glu::RenderContext&					m_renderCtx;
	const glu::ContextInfo&				m_renderCtxInfo;

	deUint32							m_format;
	deUint32							m_dataType;
	int									m_width;
	int									m_height;
	int									m_numLayers;

	glu::Texture2DArray*				m_texture;
	TextureTestUtil::TextureRenderer	m_renderer;

	int									m_curLayer;
};

Texture2DArrayFormatCase::Texture2DArrayFormatCase (tcu::TestContext& testCtx, Context& context, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height, int numLayers)
	: TestCase			(testCtx, name, description)
	, m_renderCtx		(context.getRenderContext())
	, m_renderCtxInfo	(context.getContextInfo())
	, m_format			(format)
	, m_dataType		(dataType)
	, m_width			(width)
	, m_height			(height)
	, m_numLayers		(numLayers)
	, m_texture			(DE_NULL)
	, m_renderer		(context.getRenderContext(), testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
	, m_curLayer		(0)
{
}

Texture2DArrayFormatCase::Texture2DArrayFormatCase (tcu::TestContext& testCtx, Context& context, const char* name, const char* description, deUint32 internalFormat, int width, int height, int numLayers)
	: TestCase			(testCtx, name, description)
	, m_renderCtx		(context.getRenderContext())
	, m_renderCtxInfo	(context.getContextInfo())
	, m_format			(internalFormat)
	, m_dataType		(GL_NONE)
	, m_width			(width)
	, m_height			(height)
	, m_numLayers		(numLayers)
	, m_texture			(DE_NULL)
	, m_renderer		(context.getRenderContext(), testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
	, m_curLayer		(0)
{
}

Texture2DArrayFormatCase::~Texture2DArrayFormatCase (void)
{
	deinit();
}

void Texture2DArrayFormatCase::init (void)
{
	checkSupport(m_renderCtxInfo, m_format);

	m_texture = m_dataType != GL_NONE
			  ? new glu::Texture2DArray(m_renderCtx, m_format, m_dataType, m_width, m_height, m_numLayers)	// Implicit internal format.
			  : new glu::Texture2DArray(m_renderCtx, m_format, m_width, m_height, m_numLayers);				// Explicit internal format.

	tcu::TextureFormatInfo spec = tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());

	// Fill level 0.
	m_texture->getRefTexture().allocLevel(0);
	tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), spec.valueMin, spec.valueMax);

	// Initialize state.
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	m_curLayer = 0;
}

void Texture2DArrayFormatCase::deinit (void)
{
	delete m_texture;
	m_texture = DE_NULL;

	m_renderer.clear();
}

bool Texture2DArrayFormatCase::testLayer (int layerNdx)
{
	const glw::Functions&	gl					= m_renderCtx.getFunctions();
	TestLog&				log					= m_testCtx.getLog();
	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_width, m_height, deStringHash(getName()));
	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
	vector<float>			texCoord;
	ReferenceParams			renderParams		(TEXTURETYPE_2D_ARRAY);
	tcu::TextureFormatInfo	spec				= tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());

	renderParams.samplerType	= getSamplerType(m_texture->getRefTexture().getFormat());
	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
	renderParams.colorScale		= spec.lookupScale;
	renderParams.colorBias		= spec.lookupBias;

	computeQuadTexCoord2DArray(texCoord, layerNdx, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));

	// Setup base viewport.
	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

	// Upload texture data to GL.
	m_texture->upload();

	// Bind to unit 0.
	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texture->getGLTexture());

	// Setup nearest neighbor filtering and clamp-to-edge.
	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");

	// Draw.
	m_renderer.renderQuad(0, &texCoord[0], renderParams);
	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());

	// Compute reference.
	sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], renderParams);

	// Compare and log.
	return compareImages(log, (string("Layer" + de::toString(layerNdx))).c_str(), (string("Layer " + de::toString(layerNdx))).c_str(), referenceFrame, renderedFrame, threshold);
}

Texture2DArrayFormatCase::IterateResult Texture2DArrayFormatCase::iterate (void)
{
	// Execute test for all layers.
	bool isOk = testLayer(m_curLayer);

	if (!isOk && m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");

	m_curLayer += 1;

	return m_curLayer < m_texture->getRefTexture().getNumLayers() ? CONTINUE : STOP;
}

// Texture2DFormatCase

class Texture3DFormatCase : public tcu::TestCase
{
public:
										Texture3DFormatCase		(tcu::TestContext& testCtx, Context& context, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height, int depth);
										Texture3DFormatCase		(tcu::TestContext& testCtx, Context& context, const char* name, const char* description, deUint32 internalFormat, int width, int height, int depth);
										~Texture3DFormatCase	(void);

	void								init					(void);
	void								deinit					(void);
	IterateResult						iterate					(void);

private:
										Texture3DFormatCase		(const Texture3DFormatCase& other);
	Texture3DFormatCase&				operator=				(const Texture3DFormatCase& other);

	bool								testSlice				(int sliceNdx);

	glu::RenderContext&					m_renderCtx;
	const glu::ContextInfo&				m_renderCtxInfo;

	deUint32							m_format;
	deUint32							m_dataType;
	int									m_width;
	int									m_height;
	int									m_depth;

	glu::Texture3D*						m_texture;
	TextureTestUtil::TextureRenderer	m_renderer;

	int									m_curSlice;
};

Texture3DFormatCase::Texture3DFormatCase (tcu::TestContext& testCtx, Context& context, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height, int depth)
	: TestCase			(testCtx, name, description)
	, m_renderCtx		(context.getRenderContext())
	, m_renderCtxInfo	(context.getContextInfo())
	, m_format			(format)
	, m_dataType		(dataType)
	, m_width			(width)
	, m_height			(height)
	, m_depth			(depth)
	, m_texture			(DE_NULL)
	, m_renderer		(context.getRenderContext(), testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
	, m_curSlice		(0)
{
}

Texture3DFormatCase::Texture3DFormatCase (tcu::TestContext& testCtx, Context& context, const char* name, const char* description, deUint32 internalFormat, int width, int height, int depth)
	: TestCase			(testCtx, name, description)
	, m_renderCtx		(context.getRenderContext())
	, m_renderCtxInfo	(context.getContextInfo())
	, m_format			(internalFormat)
	, m_dataType		(GL_NONE)
	, m_width			(width)
	, m_height			(height)
	, m_depth			(depth)
	, m_texture			(DE_NULL)
	, m_renderer		(context.getRenderContext(), testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
	, m_curSlice		(0)
{
}

Texture3DFormatCase::~Texture3DFormatCase (void)
{
	deinit();
}

void Texture3DFormatCase::init (void)
{
	checkSupport(m_renderCtxInfo, m_format);

	m_texture = m_dataType != GL_NONE
			  ? new glu::Texture3D(m_renderCtx, m_format, m_dataType, m_width, m_height, m_depth)	// Implicit internal format.
			  : new glu::Texture3D(m_renderCtx, m_format, m_width, m_height, m_depth);				// Explicit internal format.

	tcu::TextureFormatInfo spec = tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());

	// Fill level 0.
	m_texture->getRefTexture().allocLevel(0);
	tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), spec.valueMin, spec.valueMax);

	// Initialize state.
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	m_curSlice = 0;
}

void Texture3DFormatCase::deinit (void)
{
	delete m_texture;
	m_texture = DE_NULL;

	m_renderer.clear();
}

bool Texture3DFormatCase::testSlice (int sliceNdx)
{
	TestLog&				log					= m_testCtx.getLog();
	const glw::Functions&	gl					= m_renderCtx.getFunctions();
	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_width, m_height, deStringHash(getName()));
	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
	vector<float>			texCoord;
	ReferenceParams			renderParams		(TEXTURETYPE_3D);
	tcu::TextureFormatInfo	spec				= tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());
	float					r					= ((float)sliceNdx + 0.5f) / (float)m_depth;

	renderParams.samplerType	= getSamplerType(m_texture->getRefTexture().getFormat());
	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
	renderParams.colorScale		= spec.lookupScale;
	renderParams.colorBias		= spec.lookupBias;

	computeQuadTexCoord3D(texCoord, tcu::Vec3(0.0f, 0.0f, r), tcu::Vec3(1.0f, 1.0f, r), tcu::IVec3(0,1,2));

	// Setup base viewport.
	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

	// Upload texture data to GL.
	m_texture->upload();

	// Bind to unit 0.
	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_3D, m_texture->getGLTexture());

	// Setup nearest neighbor filtering and clamp-to-edge.
	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");

	// Draw.
	m_renderer.renderQuad(0, &texCoord[0], renderParams);
	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());

	// Compute reference.
	sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], renderParams);

	// Compare and log.
	return compareImages(log, (string("Slice" + de::toString(sliceNdx))).c_str(), (string("Slice " + de::toString(sliceNdx))).c_str(), referenceFrame, renderedFrame, threshold);
}

Texture3DFormatCase::IterateResult Texture3DFormatCase::iterate (void)
{
	// Execute test for all slices.
	bool isOk = testSlice(m_curSlice);

	if (!isOk && m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");

	m_curSlice += 1;

	return m_curSlice < m_texture->getRefTexture().getDepth() ? CONTINUE : STOP;
}

// Compressed2FormatCase

class Compressed2DFormatCase : public tcu::TestCase
{
public:
										Compressed2DFormatCase		(tcu::TestContext&				testCtx,
																	 glu::RenderContext&			renderCtx,
																	 const glu::ContextInfo&		renderCtxInfo,
																	 const char*					name,
																	 const char*					description,
																	 tcu::CompressedTexFormat		format,
																	 deUint32						randomSeed,
																	 int							width,
																	 int							height);
										~Compressed2DFormatCase		(void);

	void								init						(void);
	void								deinit						(void);
	IterateResult						iterate						(void);

private:
										Compressed2DFormatCase		(const Compressed2DFormatCase& other);
	Compressed2DFormatCase&				operator=					(const Compressed2DFormatCase& other);

	glu::RenderContext&					m_renderCtx;
	const glu::ContextInfo&				m_renderCtxInfo;

	tcu::CompressedTexFormat			m_format;

	deUint32							m_randomSeed;
	int									m_width;
	int									m_height;

	glu::Texture2D*						m_texture;
	TextureTestUtil::TextureRenderer	m_renderer;
};

Compressed2DFormatCase::Compressed2DFormatCase (tcu::TestContext&			testCtx,
												glu::RenderContext&			renderCtx,
												const glu::ContextInfo&		renderCtxInfo,
												const char*					name,
												const char*					description,
												tcu::CompressedTexFormat	format,
												deUint32					randomSeed,
												int							width,
												int							height)
	: TestCase			(testCtx, name, description)
	, m_renderCtx		(renderCtx)
	, m_renderCtxInfo	(renderCtxInfo)
	, m_format			(format)
	, m_randomSeed		(randomSeed)
	, m_width			(width)
	, m_height			(height)
	, m_texture			(DE_NULL)
	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
{
}

Compressed2DFormatCase::~Compressed2DFormatCase (void)
{
	deinit();
}

void Compressed2DFormatCase::init (void)
{
	// Create texture.
	tcu::CompressedTexture	compressedTexture	(m_format, m_width, m_height);
	int						dataSize			= compressedTexture.getDataSize();
	deUint8*				data				= (deUint8*)compressedTexture.getData();
	de::Random				rnd					(m_randomSeed);

	for (int i = 0; i < dataSize; i++)
		data[i] = rnd.getUint32() & 0xff;

	m_texture = new glu::Texture2D(m_renderCtx, m_renderCtxInfo, 1, &compressedTexture);
}

void Compressed2DFormatCase::deinit (void)
{
	delete m_texture;
	m_texture = DE_NULL;

	m_renderer.clear();
}

Compressed2DFormatCase::IterateResult Compressed2DFormatCase::iterate (void)
{
	const glw::Functions&	gl					= m_renderCtx.getFunctions();
	TestLog&				log					= m_testCtx.getLog();
	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_texture->getRefTexture().getWidth(), m_texture->getRefTexture().getHeight(), deStringHash(getName()));
	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
	vector<float>			texCoord;
	ReferenceParams			renderParams		(TEXTURETYPE_2D);
	tcu::TextureFormatInfo	spec				= tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());

	renderParams.samplerType	= getSamplerType(m_texture->getRefTexture().getFormat());
	renderParams.sampler		= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
	renderParams.colorScale		= spec.lookupScale;
	renderParams.colorBias		= spec.lookupBias;

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

	// Setup base viewport.
	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

	// Bind to unit 0.
	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());

	// Setup nearest neighbor filtering and clamp-to-edge.
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");

	// Draw.
	m_renderer.renderQuad(0, &texCoord[0], renderParams);
	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());

	// Compute reference.
	sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], renderParams);

	// Compare and log.
	bool isOk = compareImages(log, referenceFrame, renderedFrame, threshold);

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

	return STOP;
}

// CompressedCubeFormatCase

class CompressedCubeFormatCase : public tcu::TestCase
{
public:
										CompressedCubeFormatCase	(tcu::TestContext&			testCtx,
																	 glu::RenderContext&		renderCtx,
																	 const glu::ContextInfo&	renderCtxInfo,
																	 const char*				name,
																	 const char*				description,
																	 tcu::CompressedTexFormat	format,
																	 deUint32					randomSeed,
																	 int						width,
																	 int						height);

										~CompressedCubeFormatCase	(void);

	void								init						(void);
	void								deinit						(void);
	IterateResult						iterate						(void);

private:
										CompressedCubeFormatCase	(const CompressedCubeFormatCase& other);
	CompressedCubeFormatCase&			operator=					(const CompressedCubeFormatCase& other);

	bool								testFace					(tcu::CubeFace face);

	glu::RenderContext&					m_renderCtx;
	const glu::ContextInfo&				m_renderCtxInfo;

	tcu::CompressedTexFormat			m_format;

	deUint32							m_randomSeed;
	int									m_width;
	int									m_height;

	glu::TextureCube*					m_texture;
	TextureTestUtil::TextureRenderer	m_renderer;

	int									m_curFace;
	bool								m_isOk;
};

CompressedCubeFormatCase::CompressedCubeFormatCase (tcu::TestContext&			testCtx,
													glu::RenderContext&			renderCtx,
													const glu::ContextInfo&		renderCtxInfo,
													const char*					name,
													const char*					description,
													tcu::CompressedTexFormat	format,
													deUint32					randomSeed,
													int							width,
													int							height)
	: TestCase			(testCtx, name, description)
	, m_renderCtx		(renderCtx)
	, m_renderCtxInfo	(renderCtxInfo)
	, m_format			(format)
	, m_randomSeed		(randomSeed)
	, m_width			(width)
	, m_height			(height)
	, m_texture			(DE_NULL)
	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
	, m_curFace			(0)
	, m_isOk			(false)
{
}

CompressedCubeFormatCase::~CompressedCubeFormatCase (void)
{
	deinit();
}

void CompressedCubeFormatCase::init (void)
{
	vector<tcu::CompressedTexture>	levels	(tcu::CUBEFACE_LAST);
	de::Random						rnd		(m_randomSeed);

	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
	{
		levels[face].setStorage(m_format, m_width, m_height);

		int			dataSize	= levels[face].getDataSize();
		deUint8*	data		= (deUint8*)levels[face].getData();

		for (int i = 0; i < dataSize; i++)
			data[i] = rnd.getUint32() & 0xff;
	}

	m_texture = new glu::TextureCube(m_renderCtx, m_renderCtxInfo, 1, &levels[0]);

	m_curFace	= 0;
	m_isOk		= true;
}

void CompressedCubeFormatCase::deinit (void)
{
	delete m_texture;
	m_texture = DE_NULL;

	m_renderer.clear();
}

bool CompressedCubeFormatCase::testFace (tcu::CubeFace face)
{
	const glw::Functions&	gl					= m_renderCtx.getFunctions();
	TestLog&				log					= m_testCtx.getLog();
	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_texture->getRefTexture().getSize(), m_texture->getRefTexture().getSize(), deStringHash(getName())+(deUint32)face);
	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
	vector<float>			texCoord;
	ReferenceParams			renderParams		(TEXTURETYPE_CUBE);
	tcu::TextureFormatInfo	spec				= tcu::getTextureFormatInfo(m_texture->getRefTexture().getFormat());

	renderParams.samplerType				= getSamplerType(m_texture->getRefTexture().getFormat());
	renderParams.sampler					= Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
	renderParams.sampler.seamlessCubeMap	= true;
	renderParams.colorScale					= spec.lookupScale;
	renderParams.colorBias					= spec.lookupBias;

	computeQuadTexCoordCube(texCoord, face);

	log << TestLog::Message << face << TestLog::EndMessage;

	// Setup base viewport.
	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

	// Bind to unit 0.
	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());

	// Setup nearest neighbor filtering and clamp-to-edge.
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");

	m_renderer.renderQuad(0, &texCoord[0], renderParams);
	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());

	// Compute reference.
	sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], renderParams);

	// Compare and log.
	return compareImages(log, referenceFrame, renderedFrame, threshold);
}

CompressedCubeFormatCase::IterateResult CompressedCubeFormatCase::iterate (void)
{
	// Execute test for all faces.
	if (!testFace((tcu::CubeFace)m_curFace))
		m_isOk = false;

	m_curFace += 1;

	if (m_curFace == tcu::CUBEFACE_LAST)
	{
		m_testCtx.setTestResult(m_isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
								m_isOk ? "Pass"					: "Image comparison failed");
		return STOP;
	}
	else
		return CONTINUE;
}

// Texture2DFileCase

class Texture2DFileCase : public tcu::TestCase
{
public:
								Texture2DFileCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& renderCtxInfo, const char* name, const char* description, const std::vector<std::string>& filenames);
								~Texture2DFileCase		(void);

	void						init					(void);
	void						deinit					(void);
	IterateResult				iterate					(void);

private:
								Texture2DFileCase		(const Texture2DFileCase& other);
	Texture2DFileCase&			operator=				(const Texture2DFileCase& other);

	glu::RenderContext&			m_renderCtx;
	const glu::ContextInfo&		m_renderCtxInfo;

	std::vector<std::string>	m_filenames;

	glu::Texture2D*				m_texture;
	TextureRenderer				m_renderer;
};

Texture2DFileCase::Texture2DFileCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& renderCtxInfo, const char* name, const char* description, const std::vector<std::string>& filenames)
	: TestCase			(testCtx, name, description)
	, m_renderCtx		(renderCtx)
	, m_renderCtxInfo	(renderCtxInfo)
	, m_filenames		(filenames)
	, m_texture			(DE_NULL)
	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
{
}

Texture2DFileCase::~Texture2DFileCase (void)
{
	deinit();
}

void Texture2DFileCase::init (void)
{
	// Create texture.
	m_texture = glu::Texture2D::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size(), m_filenames);
}

void Texture2DFileCase::deinit (void)
{
	delete m_texture;
	m_texture = DE_NULL;

	m_renderer.clear();
}

Texture2DFileCase::IterateResult Texture2DFileCase::iterate (void)
{
	const glw::Functions&	gl					= m_renderCtx.getFunctions();
	TestLog&				log					= m_testCtx.getLog();
	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_texture->getRefTexture().getWidth(), m_texture->getRefTexture().getHeight(), deStringHash(getName()));
	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
	vector<float>			texCoord;

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

	// Setup base viewport.
	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

	// Bind to unit 0.
	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());

	// Setup nearest neighbor filtering and clamp-to-edge.
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");

	// Draw.
	m_renderer.renderQuad(0, &texCoord[0], TEXTURETYPE_2D);
	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");

	// Compute reference.
	ReferenceParams refParams(TEXTURETYPE_2D);
	refParams.sampler = Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
	sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], refParams);

	// Compare and log.
	bool isOk = compareImages(log, referenceFrame, renderedFrame, threshold);

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

	return STOP;
}

// TextureCubeFileCase

class TextureCubeFileCase : public tcu::TestCase
{
public:
								TextureCubeFileCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& renderCtxInfo, const char* name, const char* description, const std::vector<std::string>& filenames);
								~TextureCubeFileCase	(void);

	void						init					(void);
	void						deinit					(void);
	IterateResult				iterate					(void);

private:
								TextureCubeFileCase		(const TextureCubeFileCase& other);
	TextureCubeFileCase&		operator=				(const TextureCubeFileCase& other);

	bool						testFace				(tcu::CubeFace face);

	glu::RenderContext&			m_renderCtx;
	const glu::ContextInfo&		m_renderCtxInfo;

	std::vector<std::string>	m_filenames;

	glu::TextureCube*			m_texture;
	TextureRenderer				m_renderer;

	int							m_curFace;
	bool						m_isOk;
};

TextureCubeFileCase::TextureCubeFileCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& renderCtxInfo, const char* name, const char* description, const std::vector<std::string>& filenames)
	: TestCase			(testCtx, name, description)
	, m_renderCtx		(renderCtx)
	, m_renderCtxInfo	(renderCtxInfo)
	, m_filenames		(filenames)
	, m_texture			(DE_NULL)
	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
	, m_curFace			(0)
	, m_isOk			(false)
{
}

TextureCubeFileCase::~TextureCubeFileCase (void)
{
	deinit();
}

void TextureCubeFileCase::init (void)
{
	// Create texture.
	DE_ASSERT(m_filenames.size() % 6 == 0);
	m_texture = glu::TextureCube::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size()/6, m_filenames);

	m_curFace	= 0;
	m_isOk		= true;
}

void TextureCubeFileCase::deinit (void)
{
	delete m_texture;
	m_texture = DE_NULL;

	m_renderer.clear();
}

bool TextureCubeFileCase::testFace (tcu::CubeFace face)
{
	const glw::Functions&	gl					= m_renderCtx.getFunctions();
	TestLog&				log					= m_testCtx.getLog();
	RandomViewport			viewport			(m_renderCtx.getRenderTarget(), m_texture->getRefTexture().getSize(), m_texture->getRefTexture().getSize(), deStringHash(getName())+(deUint32)face);
	tcu::Surface			renderedFrame		(viewport.width, viewport.height);
	tcu::Surface			referenceFrame		(viewport.width, viewport.height);
	Sampler					sampler				(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST, Sampler::NEAREST);
	tcu::RGBA				threshold			= m_renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
	vector<float>			texCoord;

	computeQuadTexCoordCube(texCoord, face);

	// \todo [2011-10-28 pyry] Image set name / section?
	log << TestLog::Message << face << TestLog::EndMessage;

	// Setup base viewport.
	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

	// Bind to unit 0.
	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_texture->getGLTexture());

	// Setup nearest neighbor filtering and clamp-to-edge.
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");

	m_renderer.renderQuad(0, &texCoord[0], TEXTURETYPE_CUBE);
	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());
	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");

	// Compute reference.
	sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat()), m_texture->getRefTexture(), &texCoord[0], ReferenceParams(TEXTURETYPE_CUBE, sampler));

	// Compare and log.
	return compareImages(log, referenceFrame, renderedFrame, threshold);
}

TextureCubeFileCase::IterateResult TextureCubeFileCase::iterate (void)
{
	// Execute test for all faces.
	if (!testFace((tcu::CubeFace)m_curFace))
		m_isOk = false;

	m_curFace += 1;

	if (m_curFace == tcu::CUBEFACE_LAST)
	{
		m_testCtx.setTestResult(m_isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
								m_isOk ? "Pass"					: "Image comparison failed");
		return STOP;
	}
	else
		return CONTINUE;
}

// TextureFormatTests

TextureFormatTests::TextureFormatTests (Context& context)
	: TestCaseGroup(context, "format", "Texture Format Tests")
{
}

TextureFormatTests::~TextureFormatTests (void)
{
}

vector<string> toStringVector (const char* const* str, int numStr)
{
	vector<string> v;
	v.resize(numStr);
	for (int i = 0; i < numStr; i++)
		v[i] = str[i];
	return v;
}

void TextureFormatTests::init (void)
{
	tcu::TestCaseGroup* unsizedGroup	= DE_NULL;
	tcu::TestCaseGroup*	sizedGroup		= DE_NULL;
	tcu::TestCaseGroup* compressedGroup	= DE_NULL;
	addChild((unsizedGroup		= new tcu::TestCaseGroup(m_testCtx, "unsized",		"Unsized formats")));
	addChild((sizedGroup		= new tcu::TestCaseGroup(m_testCtx, "sized",		"Sized formats")));
	addChild((compressedGroup	= new tcu::TestCaseGroup(m_testCtx, "compressed",	"Compressed formats")));

	tcu::TestCaseGroup*	sized2DGroup		= DE_NULL;
	tcu::TestCaseGroup*	sizedCubeGroup		= DE_NULL;
	tcu::TestCaseGroup*	sized2DArrayGroup	= DE_NULL;
	tcu::TestCaseGroup*	sized3DGroup		= DE_NULL;
	sizedGroup->addChild((sized2DGroup			= new tcu::TestCaseGroup(m_testCtx, "2d",			"Sized formats (2D)")));
	sizedGroup->addChild((sizedCubeGroup		= new tcu::TestCaseGroup(m_testCtx, "cube",			"Sized formats (Cubemap)")));
	sizedGroup->addChild((sized2DArrayGroup		= new tcu::TestCaseGroup(m_testCtx, "2d_array",		"Sized formats (2D Array)")));
	sizedGroup->addChild((sized3DGroup			= new tcu::TestCaseGroup(m_testCtx, "3d",			"Sized formats (3D)")));

	struct
	{
		const char*	name;
		deUint32		format;
		deUint32		dataType;
	} texFormats[] =
	{
		{ "alpha",							GL_ALPHA,			GL_UNSIGNED_BYTE },
		{ "luminance",						GL_LUMINANCE,		GL_UNSIGNED_BYTE },
		{ "luminance_alpha",				GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE },
		{ "rgb_unsigned_short_5_6_5",		GL_RGB,				GL_UNSIGNED_SHORT_5_6_5 },
		{ "rgb_unsigned_byte",				GL_RGB,				GL_UNSIGNED_BYTE },
		{ "rgba_unsigned_short_4_4_4_4",	GL_RGBA,			GL_UNSIGNED_SHORT_4_4_4_4 },
		{ "rgba_unsigned_short_5_5_5_1",	GL_RGBA,			GL_UNSIGNED_SHORT_5_5_5_1 },
		{ "rgba_unsigned_byte",				GL_RGBA,			GL_UNSIGNED_BYTE }
	};

	for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(texFormats); formatNdx++)
	{
		deUint32	format			= texFormats[formatNdx].format;
		deUint32	dataType		= texFormats[formatNdx].dataType;
		string	nameBase		= texFormats[formatNdx].name;
		string	descriptionBase	= string(glu::getTextureFormatName(format)) + ", " + glu::getTypeName(dataType);

		unsizedGroup->addChild(new Texture2DFormatCase			(m_testCtx, m_context,	(nameBase + "_2d_pot").c_str(),			(descriptionBase + ", GL_TEXTURE_2D").c_str(),			format, dataType, 128, 128));
		unsizedGroup->addChild(new Texture2DFormatCase			(m_testCtx, m_context,	(nameBase + "_2d_npot").c_str(),		(descriptionBase + ", GL_TEXTURE_2D").c_str(),			format, dataType,  63, 112));
		unsizedGroup->addChild(new TextureCubeFormatCase		(m_testCtx, m_context,	(nameBase + "_cube_pot").c_str(),		(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	format, dataType,  64,  64));
		unsizedGroup->addChild(new TextureCubeFormatCase		(m_testCtx, m_context,	(nameBase + "_cube_npot").c_str(),		(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	format, dataType,  57,  57));
		unsizedGroup->addChild(new Texture2DArrayFormatCase		(m_testCtx, m_context,	(nameBase + "_2d_array_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D_ARRAY").c_str(),	format, dataType,  64,  64,  8));
		unsizedGroup->addChild(new Texture2DArrayFormatCase		(m_testCtx, m_context,	(nameBase + "_2d_array_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D_ARRAY").c_str(),	format, dataType,  63,  57,  7));
		unsizedGroup->addChild(new Texture3DFormatCase			(m_testCtx, m_context,	(nameBase + "_3d_pot").c_str(),			(descriptionBase + ", GL_TEXTURE_3D").c_str(),			format, dataType,   8,  32, 16));
		unsizedGroup->addChild(new Texture3DFormatCase			(m_testCtx, m_context,	(nameBase + "_3d_npot").c_str(),		(descriptionBase + ", GL_TEXTURE_3D").c_str(),			format, dataType,  11,  31,  7));
	}

	struct
	{
		const char*	name;
		deUint32		internalFormat;
	} sizedColorFormats[] =
	{
		{ "rgba32f",			GL_RGBA32F,			},
		{ "rgba32i",			GL_RGBA32I,			},
		{ "rgba32ui",			GL_RGBA32UI,		},
		{ "rgba16f",			GL_RGBA16F,			},
		{ "rgba16i",			GL_RGBA16I,			},
		{ "rgba16ui",			GL_RGBA16UI,		},
		{ "rgba8",				GL_RGBA8,			},
		{ "rgba8i",				GL_RGBA8I,			},
		{ "rgba8ui",			GL_RGBA8UI,			},
		{ "srgb8_alpha8",		GL_SRGB8_ALPHA8,	},
		{ "srgb_r8",			GL_SR8_EXT,			},
		{ "srgb_rg8",			GL_SRG8_EXT,		},
		{ "rgb10_a2",			GL_RGB10_A2,		},
		{ "rgb10_a2ui",			GL_RGB10_A2UI,		},
		{ "rgba4",				GL_RGBA4,			},
		{ "rgb5_a1",			GL_RGB5_A1,			},
		{ "rgba8_snorm",		GL_RGBA8_SNORM,		},
		{ "rgb8",				GL_RGB8,			},
		{ "rgb565",				GL_RGB565,			},
		{ "r11f_g11f_b10f",		GL_R11F_G11F_B10F,	},
		{ "rgb32f",				GL_RGB32F,			},
		{ "rgb32i",				GL_RGB32I,			},
		{ "rgb32ui",			GL_RGB32UI,			},
		{ "rgb16f",				GL_RGB16F,			},
		{ "rgb16i",				GL_RGB16I,			},
		{ "rgb16ui",			GL_RGB16UI,			},
		{ "rgb8_snorm",			GL_RGB8_SNORM,		},
		{ "rgb8i",				GL_RGB8I,			},
		{ "rgb8ui",				GL_RGB8UI,			},
		{ "srgb8",				GL_SRGB8,			},
		{ "rgb9_e5",			GL_RGB9_E5,			},
		{ "rg32f",				GL_RG32F,			},
		{ "rg32i",				GL_RG32I,			},
		{ "rg32ui",				GL_RG32UI,			},
		{ "rg16f",				GL_RG16F,			},
		{ "rg16i",				GL_RG16I,			},
		{ "rg16ui",				GL_RG16UI,			},
		{ "rg8",				GL_RG8,				},
		{ "rg8i",				GL_RG8I,			},
		{ "rg8ui",				GL_RG8UI,			},
		{ "rg8_snorm",			GL_RG8_SNORM,		},
		{ "r32f",				GL_R32F,			},
		{ "r32i",				GL_R32I,			},
		{ "r32ui",				GL_R32UI,			},
		{ "r16f",				GL_R16F,			},
		{ "r16i",				GL_R16I,			},
		{ "r16ui",				GL_R16UI,			},
		{ "r8",					GL_R8,				},
		{ "r8i",				GL_R8I,				},
		{ "r8ui",				GL_R8UI,			},
		{ "r8_snorm",			GL_R8_SNORM,		}
	};

	struct
	{
		const char*	name;
		deUint32		internalFormat;
	} sizedDepthStencilFormats[] =
	{
		// Depth and stencil formats
		{ "depth_component32f",	GL_DEPTH_COMPONENT32F	},
		{ "depth_component24",	GL_DEPTH_COMPONENT24	},
		{ "depth_component16",	GL_DEPTH_COMPONENT16	},
		{ "depth32f_stencil8",	GL_DEPTH32F_STENCIL8	},
		{ "depth24_stencil8",	GL_DEPTH24_STENCIL8		}
	};

	for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(sizedColorFormats); formatNdx++)
	{
		deUint32	internalFormat	= sizedColorFormats[formatNdx].internalFormat;
		string	nameBase		= sizedColorFormats[formatNdx].name;
		string	descriptionBase	= glu::getTextureFormatName(internalFormat);

		sized2DGroup->addChild		(new Texture2DFormatCase		(m_testCtx, m_context,	(nameBase + "_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D").c_str(),			internalFormat, 128, 128));
		sized2DGroup->addChild		(new Texture2DFormatCase		(m_testCtx, m_context,	(nameBase + "_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D").c_str(),			internalFormat,  63, 112));
		sizedCubeGroup->addChild	(new TextureCubeFormatCase		(m_testCtx, m_context,	(nameBase + "_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	internalFormat,  64,  64));
		sizedCubeGroup->addChild	(new TextureCubeFormatCase		(m_testCtx, m_context,	(nameBase + "_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	internalFormat,  57,  57));
		sized2DArrayGroup->addChild	(new Texture2DArrayFormatCase	(m_testCtx, m_context,	(nameBase + "_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D_ARRAY").c_str(),	internalFormat,  64,  64,  8));
		sized2DArrayGroup->addChild	(new Texture2DArrayFormatCase	(m_testCtx, m_context,	(nameBase + "_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D_ARRAY").c_str(),	internalFormat,  63,  57,  7));
		sized3DGroup->addChild		(new Texture3DFormatCase		(m_testCtx, m_context,	(nameBase + "_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_3D").c_str(),			internalFormat,   8,  32, 16));
		sized3DGroup->addChild		(new Texture3DFormatCase		(m_testCtx, m_context,	(nameBase + "_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_3D").c_str(),			internalFormat,  11,  31,  7));
	}

	for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(sizedDepthStencilFormats); formatNdx++)
	{
		deUint32	internalFormat	= sizedDepthStencilFormats[formatNdx].internalFormat;
		string	nameBase		= sizedDepthStencilFormats[formatNdx].name;
		string	descriptionBase	= glu::getTextureFormatName(internalFormat);

		sized2DGroup->addChild		(new Texture2DFormatCase		(m_testCtx, m_context,	(nameBase + "_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D").c_str(),			internalFormat, 128, 128));
		sized2DGroup->addChild		(new Texture2DFormatCase		(m_testCtx, m_context,	(nameBase + "_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D").c_str(),			internalFormat,  63, 112));
		sizedCubeGroup->addChild	(new TextureCubeFormatCase		(m_testCtx, m_context,	(nameBase + "_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	internalFormat,  64,  64));
		sizedCubeGroup->addChild	(new TextureCubeFormatCase		(m_testCtx, m_context,	(nameBase + "_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	internalFormat,  57,  57));
		sized2DArrayGroup->addChild	(new Texture2DArrayFormatCase	(m_testCtx, m_context,	(nameBase + "_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D_ARRAY").c_str(),	internalFormat,  64,  64,  8));
		sized2DArrayGroup->addChild	(new Texture2DArrayFormatCase	(m_testCtx, m_context,	(nameBase + "_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D_ARRAY").c_str(),	internalFormat,  63,  57,  7));
	}

	// ETC-1 compressed formats.
	{
		static const char* filenames[] =
		{
			"data/etc1/photo_helsinki_mip_0.pkm",
			"data/etc1/photo_helsinki_mip_1.pkm",
			"data/etc1/photo_helsinki_mip_2.pkm",
			"data/etc1/photo_helsinki_mip_3.pkm",
			"data/etc1/photo_helsinki_mip_4.pkm",
			"data/etc1/photo_helsinki_mip_5.pkm",
			"data/etc1/photo_helsinki_mip_6.pkm",
			"data/etc1/photo_helsinki_mip_7.pkm"
		};
		compressedGroup->addChild(new Texture2DFileCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), "etc1_2d_pot", "GL_ETC1_RGB8_OES, GL_TEXTURE_2D", toStringVector(filenames, DE_LENGTH_OF_ARRAY(filenames))));
	}

	{
		vector<string> filenames;
		filenames.push_back("data/etc1/photo_helsinki_113x89.pkm");
		compressedGroup->addChild(new Texture2DFileCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), "etc1_2d_npot", "GL_ETC1_RGB8_OES, GL_TEXTURE_2D", filenames));
	}

	{
		static const char* faceExt[] = { "neg_x", "pos_x", "neg_y", "pos_y", "neg_z", "pos_z" };

		const int		potNumLevels	= 7;
		vector<string>	potFilenames;
		for (int level = 0; level < potNumLevels; level++)
			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
				potFilenames.push_back(string("data/etc1/skybox_") + faceExt[face] + "_mip_" + de::toString(level) + ".pkm");

		compressedGroup->addChild(new TextureCubeFileCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), "etc1_cube_pot", "GL_ETC1_RGB8_OES, GL_TEXTURE_CUBE_MAP", potFilenames));

		vector<string> npotFilenames;
		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
			npotFilenames.push_back(string("data/etc1/skybox_61x61_") + faceExt[face] + ".pkm");

		compressedGroup->addChild(new TextureCubeFileCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), "etc1_cube_npot", "GL_ETC_RGB8_OES, GL_TEXTURE_CUBE_MAP", npotFilenames));
	}

	// ETC-2 and EAC compressed formats.
	struct {
		const char*					descriptionBase;
		const char*					nameBase;
		tcu::CompressedTexFormat	format;
	} etc2Formats[] =
	{
		{ "GL_COMPRESSED_R11_EAC",							"eac_r11",							tcu::COMPRESSEDTEXFORMAT_EAC_R11,							},
		{ "GL_COMPRESSED_SIGNED_R11_EAC",					"eac_signed_r11",					tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11,					},
		{ "GL_COMPRESSED_RG11_EAC",							"eac_rg11",							tcu::COMPRESSEDTEXFORMAT_EAC_RG11,							},
		{ "GL_COMPRESSED_SIGNED_RG11_EAC",					"eac_signed_rg11",					tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11,					},
		{ "GL_COMPRESSED_RGB8_ETC2",						"etc2_rgb8",						tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8,							},
		{ "GL_COMPRESSED_SRGB8_ETC2",						"etc2_srgb8",						tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8,						},
		{ "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2",	"etc2_rgb8_punchthrough_alpha1",	tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1,		},
		{ "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2",	"etc2_srgb8_punchthrough_alpha1",	tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1,	},
		{ "GL_COMPRESSED_RGBA8_ETC2_EAC",					"etc2_eac_rgba8",					tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8,					},
		{ "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC",			"etc2_eac_srgb8_alpha8",			tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8,				}
	};

	for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(etc2Formats); formatNdx++)
	{
		string descriptionBase	= etc2Formats[formatNdx].descriptionBase;
		string nameBase			= etc2Formats[formatNdx].nameBase;

		compressedGroup->addChild(new Compressed2DFormatCase	(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), (nameBase + "_2d_pot").c_str(),		(descriptionBase + ", GL_TEXTURE_2D").c_str(),			etc2Formats[formatNdx].format,	1,	128,	64));
		compressedGroup->addChild(new CompressedCubeFormatCase	(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), (nameBase + "_cube_pot").c_str(),		(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	etc2Formats[formatNdx].format,	1,	64,		64));
		compressedGroup->addChild(new Compressed2DFormatCase	(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), (nameBase + "_2d_npot").c_str(),		(descriptionBase + ", GL_TEXTURE_2D").c_str(),			etc2Formats[formatNdx].format,	1,	51,		65));
		compressedGroup->addChild(new CompressedCubeFormatCase	(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), (nameBase + "_cube_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	etc2Formats[formatNdx].format,	1,	51,		51));
	}


}

} // Functional
} // gles3
} // deqp
