/*-------------------------------------------------------------------------
 * 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 filtering tests.
 *//*--------------------------------------------------------------------*/

#include "es2fTextureFilteringTests.hpp"
#include "glsTextureTestUtil.hpp"
#include "gluTexture.hpp"
#include "gluStrUtil.hpp"
#include "gluTextureUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuTexLookupVerifier.hpp"
#include "tcuVectorUtil.hpp"
#include "deStringUtil.hpp"
#include "glwFunctions.hpp"
#include "glwEnums.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;

enum
{
	VIEWPORT_WIDTH		= 64,
	VIEWPORT_HEIGHT		= 64,
	MIN_VIEWPORT_WIDTH	= 64,
	MIN_VIEWPORT_HEIGHT	= 64
};

class Texture2DFilteringCase : public tcu::TestCase
{
public:
									Texture2DFilteringCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 format, deUint32 dataType, int width, int height);
									Texture2DFilteringCase		(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, const std::vector<std::string>& filenames);
									~Texture2DFilteringCase		(void);

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

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

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

	const deUint32					m_minFilter;
	const deUint32					m_magFilter;
	const deUint32					m_wrapS;
	const deUint32					m_wrapT;

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

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

	struct FilterCase
	{
		const glu::Texture2D*	texture;
		tcu::Vec2				minCoord;
		tcu::Vec2				maxCoord;

		FilterCase (void)
			: texture(DE_NULL)
		{
		}

		FilterCase (const glu::Texture2D* tex_, const tcu::Vec2& minCoord_, const tcu::Vec2& maxCoord_)
			: texture	(tex_)
			, minCoord	(minCoord_)
			, maxCoord	(maxCoord_)
		{
		}
	};

	std::vector<glu::Texture2D*>	m_textures;
	std::vector<FilterCase>			m_cases;

	TextureRenderer					m_renderer;

	int								m_caseNdx;
};

Texture2DFilteringCase::Texture2DFilteringCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 format, deUint32 dataType, int width, int height)
	: TestCase			(testCtx, name, desc)
	, m_renderCtx		(renderCtx)
	, m_renderCtxInfo	(ctxInfo)
	, m_minFilter		(minFilter)
	, m_magFilter		(magFilter)
	, m_wrapS			(wrapS)
	, m_wrapT			(wrapT)
	, m_format			(format)
	, m_dataType		(dataType)
	, m_width			(width)
	, m_height			(height)
	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
	, m_caseNdx			(0)
{
}

Texture2DFilteringCase::Texture2DFilteringCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, const std::vector<std::string>& filenames)
	: TestCase			(testCtx, name, desc)
	, m_renderCtx		(renderCtx)
	, m_renderCtxInfo	(ctxInfo)
	, m_minFilter		(minFilter)
	, m_magFilter		(magFilter)
	, m_wrapS			(wrapS)
	, m_wrapT			(wrapT)
	, m_format			(GL_NONE)
	, m_dataType		(GL_NONE)
	, m_width			(0)
	, m_height			(0)
	, m_filenames		(filenames)
	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
	, m_caseNdx			(0)
{
}

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

void Texture2DFilteringCase::init (void)
{
	try
	{
		if (!m_filenames.empty())
		{
			m_textures.reserve(1);
			m_textures.push_back(glu::Texture2D::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size(), m_filenames));
		}
		else
		{
			// Create 2 textures.
			m_textures.reserve(2);
			for (int ndx = 0; ndx < 2; ndx++)
				m_textures.push_back(new glu::Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height));

			bool					mipmaps		= deIsPowerOfTwo32(m_width) && deIsPowerOfTwo32(m_height);
			int						numLevels	= mipmaps ? deLog2Floor32(de::max(m_width, m_height))+1 : 1;
			tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat());
			tcu::Vec4				cBias		= fmtInfo.valueMin;
			tcu::Vec4				cScale		= fmtInfo.valueMax-fmtInfo.valueMin;

			// Fill first gradient texture.
			for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
			{
				tcu::Vec4 gMin = tcu::Vec4(-0.5f, -0.5f, -0.5f, 2.0f)*cScale + cBias;
				tcu::Vec4 gMax = tcu::Vec4( 1.0f,  1.0f,  1.0f, 0.0f)*cScale + cBias;

				m_textures[0]->getRefTexture().allocLevel(levelNdx);
				tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevel(levelNdx), gMin, gMax);
			}

			// Fill second with grid texture.
			for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
			{
				deUint32	step	= 0x00ffffff / numLevels;
				deUint32	rgb		= step*levelNdx;
				deUint32	colorA	= 0xff000000 | rgb;
				deUint32	colorB	= 0xff000000 | ~rgb;

				m_textures[1]->getRefTexture().allocLevel(levelNdx);
				tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevel(levelNdx), 4, toVec4(tcu::RGBA(colorA))*cScale + cBias, toVec4(tcu::RGBA(colorB))*cScale + cBias);
			}

			// Upload.
			for (std::vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
				(*i)->upload();
		}

		// Compute cases.
		{
			const struct
			{
				int		texNdx;
				float	lodX;
				float	lodY;
				float	oX;
				float	oY;
			} cases[] =
			{
				{ 0,	1.6f,	2.9f,	-1.0f,	-2.7f	},
				{ 0,	-2.0f,	-1.35f,	-0.2f,	0.7f	},
				{ 1,	0.14f,	0.275f,	-1.5f,	-1.1f	},
				{ 1,	-0.92f,	-2.64f,	0.4f,	-0.1f	},
			};

			const float	viewportW	= (float)de::min<int>(VIEWPORT_WIDTH, m_renderCtx.getRenderTarget().getWidth());
			const float	viewportH	= (float)de::min<int>(VIEWPORT_HEIGHT, m_renderCtx.getRenderTarget().getHeight());

			for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(cases); caseNdx++)
			{
				const int	texNdx	= de::clamp(cases[caseNdx].texNdx, 0, (int)m_textures.size()-1);
				const float	lodX	= cases[caseNdx].lodX;
				const float	lodY	= cases[caseNdx].lodY;
				const float	oX		= cases[caseNdx].oX;
				const float	oY		= cases[caseNdx].oY;
				const float	sX		= deFloatExp2(lodX)*viewportW / float(m_textures[texNdx]->getRefTexture().getWidth());
				const float	sY		= deFloatExp2(lodY)*viewportH / float(m_textures[texNdx]->getRefTexture().getHeight());

				m_cases.push_back(FilterCase(m_textures[texNdx], tcu::Vec2(oX, oY), tcu::Vec2(oX+sX, oY+sY)));
			}
		}

		m_caseNdx = 0;
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	catch (...)
	{
		// Clean up to save memory.
		Texture2DFilteringCase::deinit();
		throw;
	}
}

void Texture2DFilteringCase::deinit (void)
{
	for (std::vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
		delete *i;
	m_textures.clear();

	m_renderer.clear();
	m_cases.clear();
}

Texture2DFilteringCase::IterateResult Texture2DFilteringCase::iterate (void)
{
	const glw::Functions&			gl			= m_renderCtx.getFunctions();
	const RandomViewport			viewport	(m_renderCtx.getRenderTarget(), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, deStringHash(getName()) ^ deInt32Hash(m_caseNdx));
	const tcu::TextureFormat		texFmt		= m_textures[0]->getRefTexture().getFormat();
	const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFmt);
	const FilterCase&				curCase		= m_cases[m_caseNdx];
	const tcu::ScopedLogSection		section		(m_testCtx.getLog(), string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
	ReferenceParams					refParams	(TEXTURETYPE_2D);
	tcu::Surface					rendered	(viewport.width, viewport.height);
	vector<float>					texCoord;

	if (viewport.width < MIN_VIEWPORT_WIDTH || viewport.height < MIN_VIEWPORT_HEIGHT)
		throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);

	// Setup params for reference.
	refParams.sampler		= mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
	refParams.samplerType	= getSamplerType(texFmt);
	refParams.lodMode		= LODMODE_EXACT;
	refParams.colorBias		= fmtInfo.lookupBias;
	refParams.colorScale	= fmtInfo.lookupScale;

	// Compute texture coordinates.
	m_testCtx.getLog() << TestLog::Message << "Texture coordinates: " << curCase.minCoord << " -> " << curCase.maxCoord << TestLog::EndMessage;
	computeQuadTexCoord2D(texCoord, curCase.minCoord, curCase.maxCoord);

	gl.bindTexture	(GL_TEXTURE_2D, curCase.texture->getGLTexture());
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	m_magFilter);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);

	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
	m_renderer.renderQuad(0, &texCoord[0], refParams);
	glu::readPixels(m_renderCtx, viewport.x, viewport.y, rendered.getAccess());

	{
		const bool				isNearestOnly	= m_minFilter == GL_NEAREST && m_magFilter == GL_NEAREST;
		const tcu::PixelFormat	pixelFormat		= m_renderCtx.getRenderTarget().getPixelFormat();
		const tcu::IVec4		colorBits		= max(getBitsVec(pixelFormat) - (isNearestOnly ? 1 : 2), tcu::IVec4(0)); // 1 inaccurate bit if nearest only, 2 otherwise
		tcu::LodPrecision		lodPrecision;
		tcu::LookupPrecision	lookupPrecision;

		lodPrecision.derivateBits		= 7;
		lodPrecision.lodBits			= 4;
		lookupPrecision.colorThreshold	= tcu::computeFixedPointThreshold(colorBits) / refParams.colorScale;
		lookupPrecision.coordBits		= tcu::IVec3(9,9,0); // mediump interpolation
		lookupPrecision.uvwBits			= tcu::IVec3(5,5,0);
		lookupPrecision.colorMask		= getCompareMask(pixelFormat);

		const bool isOk = verifyTextureResult(m_testCtx, rendered.getAccess(), curCase.texture->getRefTexture(),
											  &texCoord[0], refParams, lookupPrecision, lodPrecision, pixelFormat);

		if (!isOk)
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
	}

	m_caseNdx += 1;
	return m_caseNdx < (int)m_cases.size() ? CONTINUE : STOP;
}


class TextureCubeFilteringCase : public tcu::TestCase
{
public:
									TextureCubeFilteringCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 format, deUint32 dataType, int width, int height);
									TextureCubeFilteringCase	(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, const std::vector<std::string>& filenames);
									~TextureCubeFilteringCase	(void);

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

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

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

	const deUint32					m_minFilter;
	const deUint32					m_magFilter;
	const deUint32					m_wrapS;
	const deUint32					m_wrapT;

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

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

	struct FilterCase
	{
		const glu::TextureCube*	texture;
		tcu::Vec2				bottomLeft;
		tcu::Vec2				topRight;

		FilterCase (void)
			: texture(DE_NULL)
		{
		}

		FilterCase (const glu::TextureCube* tex_, const tcu::Vec2& bottomLeft_, const tcu::Vec2& topRight_)
			: texture	(tex_)
			, bottomLeft(bottomLeft_)
			, topRight	(topRight_)
		{
		}
	};

	std::vector<glu::TextureCube*>	m_textures;
	std::vector<FilterCase>			m_cases;

	TextureRenderer					m_renderer;

	int								m_caseNdx;
};

TextureCubeFilteringCase::TextureCubeFilteringCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 format, deUint32 dataType, int width, int height)
	: TestCase					(testCtx, name, desc)
	, m_renderCtx				(renderCtx)
	, m_renderCtxInfo			(ctxInfo)
	, m_minFilter				(minFilter)
	, m_magFilter				(magFilter)
	, m_wrapS					(wrapS)
	, m_wrapT					(wrapT)
	, m_format					(format)
	, m_dataType				(dataType)
	, m_width					(width)
	, m_height					(height)
	, m_renderer				(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
	, m_caseNdx					(0)
{
}

TextureCubeFilteringCase::TextureCubeFilteringCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, const std::vector<std::string>& filenames)
	: TestCase					(testCtx, name, desc)
	, m_renderCtx				(renderCtx)
	, m_renderCtxInfo			(ctxInfo)
	, m_minFilter				(minFilter)
	, m_magFilter				(magFilter)
	, m_wrapS					(wrapS)
	, m_wrapT					(wrapT)
	, m_format					(GL_NONE)
	, m_dataType				(GL_NONE)
	, m_width					(0)
	, m_height					(0)
	, m_filenames				(filenames)
	, m_renderer				(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_100_ES, glu::PRECISION_MEDIUMP)
	, m_caseNdx					(0)
{
}

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

void TextureCubeFilteringCase::init (void)
{
	try
	{
		if (!m_filenames.empty())
		{
			m_textures.reserve(1);
			m_textures.push_back(glu::TextureCube::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size() / 6, m_filenames));
		}
		else
		{
			DE_ASSERT(m_width == m_height);
			m_textures.reserve(2);
			for (int ndx = 0; ndx < 2; ndx++)
				m_textures.push_back(new glu::TextureCube(m_renderCtx, m_format, m_dataType, m_width));

			const bool				mipmaps		= deIsPowerOfTwo32(m_width) && deIsPowerOfTwo32(m_height);
			const int				numLevels	= mipmaps ? deLog2Floor32(de::max(m_width, m_height))+1 : 1;
			tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat());
			tcu::Vec4				cBias		= fmtInfo.valueMin;
			tcu::Vec4				cScale		= fmtInfo.valueMax-fmtInfo.valueMin;

			// Fill first with gradient texture.
			static const tcu::Vec4 gradients[tcu::CUBEFACE_LAST][2] =
			{
				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative x
				{ tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive x
				{ tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative y
				{ tcu::Vec4(0.0f, 0.0f, 0.5f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive y
				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f) }, // negative z
				{ tcu::Vec4(0.5f, 0.5f, 0.5f, 1.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }  // positive z
			};
			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
			{
				for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
				{
					m_textures[0]->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx);
					tcu::fillWithComponentGradients(m_textures[0]->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face), gradients[face][0]*cScale + cBias, gradients[face][1]*cScale + cBias);
				}
			}

			// Fill second with grid texture.
			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
			{
				for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
				{
					deUint32	step	= 0x00ffffff / (numLevels*tcu::CUBEFACE_LAST);
					deUint32	rgb		= step*levelNdx*face;
					deUint32	colorA	= 0xff000000 | rgb;
					deUint32	colorB	= 0xff000000 | ~rgb;

					m_textures[1]->getRefTexture().allocLevel((tcu::CubeFace)face, levelNdx);
					tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face), 4, toVec4(tcu::RGBA(colorA))*cScale + cBias, toVec4(tcu::RGBA(colorB))*cScale + cBias);
				}
			}

			// Upload.
			for (std::vector<glu::TextureCube*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
				(*i)->upload();
		}

		// Compute cases
		{
			const glu::TextureCube*	tex0	= m_textures[0];
			const glu::TextureCube* tex1	= m_textures.size() > 1 ? m_textures[1] : tex0;

			// \note Coordinates are chosen so that they only sample face interior. ES3 has changed edge sampling behavior
			//		 and hw is not expected to implement both modes.
			m_cases.push_back(FilterCase(tex0, tcu::Vec2(-0.8f, -0.8f), tcu::Vec2(0.8f, 0.8f)));	// minification
			m_cases.push_back(FilterCase(tex0, tcu::Vec2(0.5f, 0.65f), tcu::Vec2(0.8f, 0.8f)));		// magnification
			m_cases.push_back(FilterCase(tex1, tcu::Vec2(-0.8f, -0.8f), tcu::Vec2(0.8f, 0.8f)));	// minification
			m_cases.push_back(FilterCase(tex1, tcu::Vec2(0.2f, 0.2f), tcu::Vec2(0.6f, 0.5f)));		// magnification
		}

		m_caseNdx = 0;
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	}
	catch (...)
	{
		// Clean up to save memory.
		TextureCubeFilteringCase::deinit();
		throw;
	}
}

void TextureCubeFilteringCase::deinit (void)
{
	for (std::vector<glu::TextureCube*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
		delete *i;
	m_textures.clear();

	m_renderer.clear();
	m_cases.clear();
}

static const char* getFaceDesc (const tcu::CubeFace face)
{
	switch (face)
	{
		case tcu::CUBEFACE_NEGATIVE_X:	return "-X";
		case tcu::CUBEFACE_POSITIVE_X:	return "+X";
		case tcu::CUBEFACE_NEGATIVE_Y:	return "-Y";
		case tcu::CUBEFACE_POSITIVE_Y:	return "+Y";
		case tcu::CUBEFACE_NEGATIVE_Z:	return "-Z";
		case tcu::CUBEFACE_POSITIVE_Z:	return "+Z";
		default:
			DE_ASSERT(false);
			return DE_NULL;
	}
}

TextureCubeFilteringCase::IterateResult TextureCubeFilteringCase::iterate (void)
{
	const glw::Functions&			gl				= m_renderCtx.getFunctions();
	const int						viewportSize	= 28;
	const RandomViewport			viewport		(m_renderCtx.getRenderTarget(), viewportSize, viewportSize, deStringHash(getName()) ^ deInt32Hash(m_caseNdx));
	const tcu::ScopedLogSection		iterSection		(m_testCtx.getLog(), string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
	const FilterCase&				curCase			= m_cases[m_caseNdx];
	const tcu::TextureFormat&		texFmt			= curCase.texture->getRefTexture().getFormat();
	const tcu::TextureFormatInfo	fmtInfo			= tcu::getTextureFormatInfo(texFmt);
	ReferenceParams					sampleParams	(TEXTURETYPE_CUBE);

	if (viewport.width < viewportSize || viewport.height < viewportSize)
		throw tcu::NotSupportedError("Too small render target", DE_NULL, __FILE__, __LINE__);

	// Setup texture
	gl.bindTexture	(GL_TEXTURE_CUBE_MAP, curCase.texture->getGLTexture());
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	m_minFilter);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	m_magFilter);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		m_wrapS);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		m_wrapT);

	// Other state
	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);

	// Params for reference computation.
	sampleParams.sampler					= glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
	sampleParams.sampler.seamlessCubeMap	= true;
	sampleParams.samplerType				= getSamplerType(texFmt);
	sampleParams.colorBias					= fmtInfo.lookupBias;
	sampleParams.colorScale					= fmtInfo.lookupScale;
	sampleParams.lodMode					= LODMODE_EXACT;

	m_testCtx.getLog() << TestLog::Message << "Coordinates: " << curCase.bottomLeft << " -> " << curCase.topRight << TestLog::EndMessage;

	for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
	{
		const tcu::CubeFace		face		= tcu::CubeFace(faceNdx);
		tcu::Surface			result		(viewport.width, viewport.height);
		vector<float>			texCoord;

		computeQuadTexCoordCube(texCoord, face, curCase.bottomLeft, curCase.topRight);

		m_testCtx.getLog() << TestLog::Message << "Face " << getFaceDesc(face) << TestLog::EndMessage;

		// \todo Log texture coordinates.

		m_renderer.renderQuad(0, &texCoord[0], sampleParams);
		GLU_EXPECT_NO_ERROR(gl.getError(), "Draw");

		glu::readPixels(m_renderCtx, viewport.x, viewport.y, result.getAccess());
		GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels");

		{
			const bool				isNearestOnly	= m_minFilter == GL_NEAREST && m_magFilter == GL_NEAREST;
			const tcu::PixelFormat	pixelFormat		= m_renderCtx.getRenderTarget().getPixelFormat();
			const tcu::IVec4		colorBits		= max(getBitsVec(pixelFormat) - (isNearestOnly ? 1 : 2), tcu::IVec4(0)); // 1 inaccurate bit if nearest only, 2 otherwise
			tcu::LodPrecision		lodPrecision;
			tcu::LookupPrecision	lookupPrecision;

			lodPrecision.derivateBits		= 5;
			lodPrecision.lodBits			= 3;
			lookupPrecision.colorThreshold	= tcu::computeFixedPointThreshold(colorBits) / sampleParams.colorScale;
			lookupPrecision.coordBits		= tcu::IVec3(9,9,9); // mediump interpolation
			lookupPrecision.uvwBits			= tcu::IVec3(5,5,0);
			lookupPrecision.colorMask		= getCompareMask(pixelFormat);

			const bool isOk = verifyTextureResult(m_testCtx, result.getAccess(), curCase.texture->getRefTexture(),
												  &texCoord[0], sampleParams, lookupPrecision, lodPrecision, pixelFormat);

			if (!isOk)
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
		}
	}

	m_caseNdx += 1;
	return m_caseNdx < (int)m_cases.size() ? CONTINUE : STOP;
}

TextureFilteringTests::TextureFilteringTests (Context& context)
	: TestCaseGroup(context, "filtering", "Texture Filtering Tests")
{
}

TextureFilteringTests::~TextureFilteringTests (void)
{
}

void TextureFilteringTests::init (void)
{
	tcu::TestCaseGroup* group2D		= new tcu::TestCaseGroup(m_testCtx, "2d",	"2D Texture Filtering");
	tcu::TestCaseGroup*	groupCube	= new tcu::TestCaseGroup(m_testCtx, "cube",	"Cube Map Filtering");
	addChild(group2D);
	addChild(groupCube);

	static const struct
	{
		const char*		name;
		deUint32		mode;
	} wrapModes[] =
	{
		{ "clamp",		GL_CLAMP_TO_EDGE },
		{ "repeat",		GL_REPEAT },
		{ "mirror",		GL_MIRRORED_REPEAT }
	};

	static const struct
	{
		const char*		name;
		deUint32		mode;
	} minFilterModes[] =
	{
		{ "nearest",				GL_NEAREST					},
		{ "linear",					GL_LINEAR					},
		{ "nearest_mipmap_nearest",	GL_NEAREST_MIPMAP_NEAREST	},
		{ "linear_mipmap_nearest",	GL_LINEAR_MIPMAP_NEAREST	},
		{ "nearest_mipmap_linear",	GL_NEAREST_MIPMAP_LINEAR	},
		{ "linear_mipmap_linear",	GL_LINEAR_MIPMAP_LINEAR		}
	};

	static const struct
	{
		const char*		name;
		deUint32		mode;
	} magFilterModes[] =
	{
		{ "nearest",	GL_NEAREST },
		{ "linear",		GL_LINEAR }
	};

	static const struct
	{
		const char*		name;
		int				width;
		int				height;
	} sizes2D[] =
	{
		{ "pot",		32, 64 },
		{ "npot",		31, 55 }
	};

	static const struct
	{
		const char*		name;
		int				width;
		int				height;
	} sizesCube[] =
	{
		{ "pot",		64, 64 },
		{ "npot",		63, 63 }
	};

	static const struct
	{
		const char*		name;
		deUint32		format;
		deUint32		dataType;
	} formats[] =
	{
		{ "rgba8888",	GL_RGBA,			GL_UNSIGNED_BYTE			},
		{ "rgb888",		GL_RGB,				GL_UNSIGNED_BYTE			},
		{ "rgba4444",	GL_RGBA,			GL_UNSIGNED_SHORT_4_4_4_4	},
		{ "l8",			GL_LUMINANCE,		GL_UNSIGNED_BYTE			}
	};

#define FOR_EACH(ITERATOR, ARRAY, BODY)	\
	for (int ITERATOR = 0; ITERATOR < DE_LENGTH_OF_ARRAY(ARRAY); ITERATOR++)	\
		BODY

	// 2D cases.
	FOR_EACH(minFilter,		minFilterModes,
	FOR_EACH(magFilter,		magFilterModes,
	FOR_EACH(wrapMode,		wrapModes,
	FOR_EACH(format,		formats,
	FOR_EACH(size,			sizes2D,
		{
			bool isMipmap		= minFilterModes[minFilter].mode != GL_NEAREST && minFilterModes[minFilter].mode != GL_LINEAR;
			bool isClamp		= wrapModes[wrapMode].mode == GL_CLAMP_TO_EDGE;
			bool isRepeat		= wrapModes[wrapMode].mode == GL_REPEAT;
			bool isMagNearest	= magFilterModes[magFilter].mode == GL_NEAREST;
			bool isPotSize		= deIsPowerOfTwo32(sizes2D[size].width) && deIsPowerOfTwo32(sizes2D[size].height);

			if ((isMipmap || !isClamp) && !isPotSize)
				continue; // Not supported.

			if ((format != 0) && !(!isMipmap || (isRepeat && isMagNearest)))
				continue; // Skip.

			string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name + "_" + formats[format].name;

			if (!isMipmap)
				name += string("_") + sizes2D[size].name;

			group2D->addChild(new Texture2DFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
														 name.c_str(), "",
														 minFilterModes[minFilter].mode,
														 magFilterModes[magFilter].mode,
														 wrapModes[wrapMode].mode,
														 wrapModes[wrapMode].mode,
														 formats[format].format, formats[format].dataType,
														 sizes2D[size].width, sizes2D[size].height));
		})))));

	// 2D ETC1 texture cases.
	{
		std::vector<std::string> filenames;
		for (int i = 0; i <= 7; i++)
			filenames.push_back(string("data/etc1/photo_helsinki_mip_") + de::toString(i) + ".pkm");

		FOR_EACH(minFilter,		minFilterModes,
		FOR_EACH(magFilter,		magFilterModes,
		FOR_EACH(wrapMode,		wrapModes,
			{
				string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name + "_etc1";

				group2D->addChild(new Texture2DFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
															 name.c_str(), "",
															 minFilterModes[minFilter].mode,
															 magFilterModes[magFilter].mode,
															 wrapModes[wrapMode].mode,
															 wrapModes[wrapMode].mode,
															 filenames));
			})));
	}

	// Cubemap cases.
	FOR_EACH(minFilter,		minFilterModes,
	FOR_EACH(magFilter,		magFilterModes,
	FOR_EACH(wrapMode,		wrapModes,
	FOR_EACH(format,		formats,
	FOR_EACH(size,			sizesCube,
		{
			bool isMipmap		= minFilterModes[minFilter].mode != GL_NEAREST && minFilterModes[minFilter].mode != GL_LINEAR;
			bool isClamp		= wrapModes[wrapMode].mode == GL_CLAMP_TO_EDGE;
			bool isRepeat		= wrapModes[wrapMode].mode == GL_REPEAT;
			bool isMagNearest	= magFilterModes[magFilter].mode == GL_NEAREST;
			bool isPotSize		= deIsPowerOfTwo32(sizesCube[size].width) && deIsPowerOfTwo32(sizesCube[size].height);

			if ((isMipmap || !isClamp) && !isPotSize)
				continue; // Not supported.

			if (format != 0 && !(!isMipmap || (isRepeat && isMagNearest)))
				continue; // Skip.

			string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name + "_" + formats[format].name;

			if (!isMipmap)
				name += string("_") + sizesCube[size].name;

			groupCube->addChild(new TextureCubeFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
															 name.c_str(), "",
															 minFilterModes[minFilter].mode,
															 magFilterModes[magFilter].mode,
															 wrapModes[wrapMode].mode,
															 wrapModes[wrapMode].mode,
															 formats[format].format, formats[format].dataType,
															 sizesCube[size].width, sizesCube[size].height));
		})))));

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

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

		FOR_EACH(minFilter,		minFilterModes,
		FOR_EACH(magFilter,		magFilterModes,
			{
				string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_clamp_etc1";

				groupCube->addChild(new TextureCubeFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
																 name.c_str(), "",
																 minFilterModes[minFilter].mode,
																 magFilterModes[magFilter].mode,
																 GL_CLAMP_TO_EDGE,
																 GL_CLAMP_TO_EDGE,
																 filenames));
			}));
	}
}

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