/*-------------------------------------------------------------------------
 * 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 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 "es2fTextureFormatTests.hpp"
#include "glsTextureTestUtil.hpp"
#include "gluTexture.hpp"
#include "gluStrUtil.hpp"
#include "gluTextureUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "tcuSurfaceAccess.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"

#include "deStringUtil.hpp"

#include "glwEnums.hpp"
#include "glwFunctions.hpp"

namespace deqp
{
namespace gles2
{
namespace Functional
{

using tcu::TestLog;
using std::vector;
using std::string;
using tcu::Sampler;
using namespace glu;
using namespace gls::TextureTestUtil;
using namespace glu::TextureTestUtil;

// Texture2DFormatCase

class Texture2DFormatCase : public tcu::TestCase
{
public:
							Texture2DFormatCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, 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 deUint32			m_format;
	const deUint32			m_dataType;
	const int				m_width;
	const int				m_height;

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

Texture2DFormatCase::Texture2DFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height)
	: TestCase		(testCtx, name, description)
	, m_renderCtx	(renderCtx)
	, m_format		(format)
	, m_dataType	(dataType)
	, m_width		(width)
	, m_height		(height)
	, m_texture		(DE_NULL)
	, m_renderer	(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
{
}

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

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

	fmtName << getTextureFormatStr(m_format) << ", " << getTypeStr(m_dataType);

	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 = new Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height);

	// 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 = " << getTextureParameterValueStr(GL_TEXTURE_WRAP_S, wrapS)
							<< "\n  WRAP_T = " << getTextureParameterValueStr(GL_TEXTURE_WRAP_T, wrapT)
							<< "\n  MIN_FILTER = " << getTextureParameterValueStr(GL_TEXTURE_MIN_FILTER, minFilter)
							<< "\n  MAG_FILTER = " << 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, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, 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 deUint32			m_format;
	const deUint32			m_dataType;
	const int				m_width;
	const int				m_height;

	glu::TextureCube*		m_texture;
	TextureRenderer			m_renderer;

	int						m_curFace;
	bool					m_isOk;
};


TextureCubeFormatCase::TextureCubeFormatCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, deUint32 format, deUint32 dataType, int width, int height)
	: TestCase		(testCtx, name, description)
	, m_renderCtx	(renderCtx)
	, m_format		(format)
	, m_dataType	(dataType)
	, m_width		(width)
	, m_height		(height)
	, m_texture		(DE_NULL)
	, m_renderer	(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
	, m_curFace		(0)
	, m_isOk		(false)
{
}

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

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

	if (m_dataType)
		fmtName << getTextureFormatStr(m_format) << ", " << getTypeStr(m_dataType);
	else
		fmtName << 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 TextureCube(m_renderCtx, m_format, m_dataType, m_width)	// Implicit internal format.
		      : new 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)
{
	const glw::Functions&	gl					= m_renderCtx.getFunctions();
	TestLog&				log					= m_testCtx.getLog();
	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	= false;
	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;
}

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

TextureFormatTests::~TextureFormatTests (void)
{
}

// Compressed2DFormatCase

class Compressed2DFormatCase : public tcu::TestCase
{
public:
								Compressed2DFormatCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& renderCtxInfo, const char* name, const char* description, const std::vector<std::string>& filenames);
								~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;

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

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

Compressed2DFormatCase::Compressed2DFormatCase (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_100_ES, glu::PRECISION_MEDIUMP)
{
}

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

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

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;

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

// CompressedCubeFormatCase

class CompressedCubeFormatCase : public tcu::TestCase
{
public:
								CompressedCubeFormatCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& renderCtxInfo, const char* name, const char* description, const std::vector<std::string>& filenames);
								~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;

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

	glu::TextureCube*			m_texture;
	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, 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_100_ES, glu::PRECISION_MEDIUMP)
	, m_curFace			(0)
	, m_isOk			(false)
{
}

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

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

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

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

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)
{
	struct
	{
		const char*	name;
		deUint32		format;
		deUint32		dataType;
	} texFormats[] =
	{
		{ "a8",			GL_ALPHA,			GL_UNSIGNED_BYTE },
		{ "l8",			GL_LUMINANCE,		GL_UNSIGNED_BYTE },
		{ "la88",		GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE },
		{ "rgb565",		GL_RGB,				GL_UNSIGNED_SHORT_5_6_5 },
		{ "rgb888",		GL_RGB,				GL_UNSIGNED_BYTE },
		{ "rgba4444",	GL_RGBA,			GL_UNSIGNED_SHORT_4_4_4_4 },
		{ "rgba5551",	GL_RGBA,			GL_UNSIGNED_SHORT_5_5_5_1 },
		{ "rgba8888",	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);

		addChild(new Texture2DFormatCase	(m_testCtx, m_context.getRenderContext(),	(nameBase + "_2d_pot").c_str(),		(descriptionBase + ", GL_TEXTURE_2D").c_str(),			format, dataType, 128, 128));
		addChild(new Texture2DFormatCase	(m_testCtx, m_context.getRenderContext(),	(nameBase + "_2d_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_2D").c_str(),			format, dataType,  63, 112));
		addChild(new TextureCubeFormatCase	(m_testCtx, m_context.getRenderContext(),	(nameBase + "_cube_pot").c_str(),	(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	format, dataType,  64,  64));
		addChild(new TextureCubeFormatCase	(m_testCtx, m_context.getRenderContext(),	(nameBase + "_cube_npot").c_str(),	(descriptionBase + ", GL_TEXTURE_CUBE_MAP").c_str(),	format, dataType,  57,  57));
	}

	// 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"
		};
		addChild(new Compressed2DFormatCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), "etc1_2d_pot", "GL_ETC1_RGB8_OES, GL_TEXTURE_2D", toStringVector(filenames, DE_LENGTH_OF_ARRAY(filenames))));
	}

	{
		vector<string> filenames;
		filenames.push_back("data/etc1/photo_helsinki_113x89.pkm");
		addChild(new Compressed2DFormatCase(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");

		addChild(new CompressedCubeFormatCase(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");

		addChild(new CompressedCubeFormatCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), "etc1_cube_npot", "GL_ETC_RGB8_OES, GL_TEXTURE_CUBE_MAP", npotFilenames));
	}
}

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