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

#include "es3fTextureFilteringTests.hpp"
#include "glsTextureTestUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "gluTexture.hpp"
#include "gluTextureUtil.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuImageCompare.hpp"
#include "tcuTexLookupVerifier.hpp"
#include "tcuVectorUtil.hpp"
#include "deStringUtil.hpp"
#include "deString.h"
#include "glwFunctions.hpp"
#include "glwEnums.hpp"
#include "gluContextInfo.hpp"
#include "deUniquePtr.hpp"

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

namespace deqp
{
namespace gles3
{
namespace Functional
{

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

enum
{
	TEX2D_VIEWPORT_WIDTH		= 64,
	TEX2D_VIEWPORT_HEIGHT		= 64,
	TEX2D_MIN_VIEWPORT_WIDTH	= 64,
	TEX2D_MIN_VIEWPORT_HEIGHT	= 64,

	TEX3D_VIEWPORT_WIDTH		= 64,
	TEX3D_VIEWPORT_HEIGHT		= 64,
	TEX3D_MIN_VIEWPORT_WIDTH	= 64,
	TEX3D_MIN_VIEWPORT_HEIGHT	= 64
};

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_decode is not supported.");
}

} // anonymous

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 internalFormat, 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_internalFormat;
	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 internalFormat, 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_internalFormat	(internalFormat)
	, m_width			(width)
	, m_height			(height)
	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
	, 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_internalFormat	(GL_NONE)
	, m_width			(0)
	, m_height			(0)
	, m_filenames		(filenames)
	, m_renderer		(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
	, m_caseNdx			(0)
{
}

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

void Texture2DFilteringCase::init (void)
{
	checkSupport(m_renderCtxInfo, m_internalFormat);

	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_internalFormat, m_width, m_height));

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

			// Fill first gradient texture.
			for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
			{
				tcu::Vec4 gMin = tcu::Vec4(0.0f, 0.0f, 0.0f, 1.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, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*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>(TEX2D_VIEWPORT_WIDTH, m_renderCtx.getRenderTarget().getWidth());
			const float	viewportH	= (float)de::min<int>(TEX2D_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(), TEX2D_VIEWPORT_WIDTH, TEX2D_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 < TEX2D_MIN_VIEWPORT_WIDTH || viewport.height < TEX2D_MIN_VIEWPORT_HEIGHT)
		throw tcu::NotSupportedError("Too small render target", "", __FILE__, __LINE__);

	// Setup params for reference.
	refParams.sampler		= glu::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		= 18;
		lodPrecision.lodBits			= 6;
		lookupPrecision.colorThreshold	= tcu::computeFixedPointThreshold(colorBits) / refParams.colorScale;
		lookupPrecision.coordBits		= tcu::IVec3(20,20,0);
		lookupPrecision.uvwBits			= tcu::IVec3(7,7,0);
		lookupPrecision.colorMask		= getCompareMask(pixelFormat);

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

		if (!isHighQuality)
		{
			// Evaluate against lower precision requirements.
			lodPrecision.lodBits	= 4;
			lookupPrecision.uvwBits	= tcu::IVec3(4,4,0);

			m_testCtx.getLog() << TestLog::Message << "Warning: Verification against high precision requirements failed, trying with lower requirements." << TestLog::EndMessage;

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

			if (!isOk)
			{
				m_testCtx.getLog() << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
			}
			else if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
				m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality filtering result");
		}
	}

	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, bool onlySampleFaceInterior, deUint32 internalFormat, 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, bool onlySampleFaceInterior, 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 bool						m_onlySampleFaceInterior; //!< If true, we avoid sampling anywhere near a face's edges.

	const deUint32					m_internalFormat;
	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, bool onlySampleFaceInterior, deUint32 internalFormat, 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_onlySampleFaceInterior	(onlySampleFaceInterior)
	, m_internalFormat			(internalFormat)
	, m_width					(width)
	, m_height					(height)
	, m_renderer				(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
	, 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, bool onlySampleFaceInterior, 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_onlySampleFaceInterior	(onlySampleFaceInterior)
	, m_internalFormat			(GL_NONE)
	, m_width					(0)
	, m_height					(0)
	, m_filenames				(filenames)
	, m_renderer				(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
	, m_caseNdx					(0)
{
}

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

void TextureCubeFilteringCase::init (void)
{
	checkSupport(m_renderCtxInfo, m_internalFormat);

	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_internalFormat, m_width));

			const int				numLevels	= deLog2Floor32(de::max(m_width, m_height))+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, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*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;

			if (m_onlySampleFaceInterior)
			{
				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
			}
			else
			{
				if (m_renderCtx.getRenderTarget().getNumSamples() == 0)
					m_cases.push_back(FilterCase(tex0, tcu::Vec2(-1.25f, -1.2f), tcu::Vec2(1.2f, 1.25f)));	// minification
				else
					m_cases.push_back(FilterCase(tex0, tcu::Vec2(-1.19f, -1.3f), tcu::Vec2(1.1f, 1.35f)));	// minification - w/ tweak to avoid hitting triangle edges with face switchpoint

				m_cases.push_back(FilterCase(tex0, tcu::Vec2(0.8f, 0.8f), tcu::Vec2(1.25f, 1.20f)));	// magnification
				m_cases.push_back(FilterCase(tex1, tcu::Vec2(-1.19f, -1.3f), tcu::Vec2(1.1f, 1.35f)));	// minification
				m_cases.push_back(FilterCase(tex1, tcu::Vec2(-1.2f, -1.1f), tcu::Vec2(-0.8f, -0.8f)));	// 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(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, 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		= 10;
			lodPrecision.lodBits			= 5;
			lookupPrecision.colorThreshold	= tcu::computeFixedPointThreshold(colorBits) / sampleParams.colorScale;
			lookupPrecision.coordBits		= tcu::IVec3(10,10,10);
			lookupPrecision.uvwBits			= tcu::IVec3(6,6,0);
			lookupPrecision.colorMask		= getCompareMask(pixelFormat);

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

			if (!isHighQuality)
			{
				// Evaluate against lower precision requirements.
				lodPrecision.lodBits	= 4;
				lookupPrecision.uvwBits	= tcu::IVec3(4,4,0);

				m_testCtx.getLog() << TestLog::Message << "Warning: Verification against high precision requirements failed, trying with lower requirements." << TestLog::EndMessage;

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

				if (!isOk)
				{
					m_testCtx.getLog() << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
					m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
				}
				else if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
					m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality filtering result");
			}
		}
	}

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

// 2D array filtering

class Texture2DArrayFilteringCase : public TestCase
{
public:
									Texture2DArrayFilteringCase		(Context& context, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 internalFormat, int width, int height, int numLayers);
									~Texture2DArrayFilteringCase	(void);

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

private:
									Texture2DArrayFilteringCase		(const Texture2DArrayFilteringCase&);
	Texture2DArrayFilteringCase&	operator=						(const Texture2DArrayFilteringCase&);

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

	const deUint32					m_internalFormat;
	const int						m_width;
	const int						m_height;
	const int						m_numLayers;

	struct FilterCase
	{
		const glu::Texture2DArray*	texture;
		tcu::Vec2					lod;
		tcu::Vec2					offset;
		tcu::Vec2					layerRange;

		FilterCase (void)
			: texture(DE_NULL)
		{
		}

		FilterCase (const glu::Texture2DArray* tex_, const tcu::Vec2& lod_, const tcu::Vec2& offset_, const tcu::Vec2& layerRange_)
			: texture	(tex_)
			, lod		(lod_)
			, offset	(offset_)
			, layerRange(layerRange_)
		{
		}
	};

	glu::Texture2DArray*			m_gradientTex;
	glu::Texture2DArray*			m_gridTex;

	TextureRenderer					m_renderer;

	std::vector<FilterCase>			m_cases;
	int								m_caseNdx;
};

Texture2DArrayFilteringCase::Texture2DArrayFilteringCase (Context& context, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 internalFormat, int width, int height, int numLayers)
	: TestCase			(context, name, desc)
	, m_minFilter		(minFilter)
	, m_magFilter		(magFilter)
	, m_wrapS			(wrapS)
	, m_wrapT			(wrapT)
	, m_internalFormat	(internalFormat)
	, m_width			(width)
	, m_height			(height)
	, m_numLayers		(numLayers)
	, m_gradientTex		(DE_NULL)
	, m_gridTex			(DE_NULL)
	, m_renderer		(context.getRenderContext(), context.getTestContext().getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
	, m_caseNdx			(0)
{
}

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

void Texture2DArrayFilteringCase::init (void)
{
	checkSupport(m_context.getContextInfo(), m_internalFormat);

	try
	{
		const tcu::TextureFormat		texFmt		= glu::mapGLInternalFormat(m_internalFormat);
		const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFmt);
		const tcu::Vec4					cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
		const tcu::Vec4					cBias		= fmtInfo.valueMin;
		const int						numLevels	= deLog2Floor32(de::max(m_width, m_height)) + 1;

		// Create textures.
		m_gradientTex	= new glu::Texture2DArray(m_context.getRenderContext(), m_internalFormat, m_width, m_height, m_numLayers);
		m_gridTex		= new glu::Texture2DArray(m_context.getRenderContext(), m_internalFormat, m_width, m_height, m_numLayers);

		const tcu::IVec4 levelSwz[] =
		{
			tcu::IVec4(0,1,2,3),
			tcu::IVec4(2,1,3,0),
			tcu::IVec4(3,0,1,2),
			tcu::IVec4(1,3,2,0),
		};

		// Fill first gradient texture (gradient direction varies between layers).
		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
		{
			m_gradientTex->getRefTexture().allocLevel(levelNdx);

			const tcu::PixelBufferAccess levelBuf = m_gradientTex->getRefTexture().getLevel(levelNdx);

			for (int layerNdx = 0; layerNdx < m_numLayers; layerNdx++)
			{
				const tcu::IVec4	swz		= levelSwz[layerNdx%DE_LENGTH_OF_ARRAY(levelSwz)];
				const tcu::Vec4		gMin	= tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f).swizzle(swz[0],swz[1],swz[2],swz[3])*cScale + cBias;
				const tcu::Vec4		gMax	= tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f).swizzle(swz[0],swz[1],swz[2],swz[3])*cScale + cBias;

				tcu::fillWithComponentGradients(tcu::getSubregion(levelBuf, 0, 0, layerNdx, levelBuf.getWidth(), levelBuf.getHeight(), 1), gMin, gMax);
			}
		}

		// Fill second with grid texture (each layer has unique colors).
		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
		{
			m_gridTex->getRefTexture().allocLevel(levelNdx);

			const tcu::PixelBufferAccess levelBuf = m_gridTex->getRefTexture().getLevel(levelNdx);

			for (int layerNdx = 0; layerNdx < m_numLayers; layerNdx++)
			{
				const deUint32	step	= 0x00ffffff / (numLevels*m_numLayers - 1);
				const deUint32	rgb		= step * (levelNdx + layerNdx*numLevels);
				const deUint32	colorA	= 0xff000000 | rgb;
				const deUint32	colorB	= 0xff000000 | ~rgb;

				tcu::fillWithGrid(tcu::getSubregion(levelBuf, 0, 0, layerNdx, levelBuf.getWidth(), levelBuf.getHeight(), 1),
								  4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
			}
		}

		// Upload.
		m_gradientTex->upload();
		m_gridTex->upload();

		// Test cases
		m_cases.push_back(FilterCase(m_gradientTex,	tcu::Vec2( 1.5f,  2.8f  ),	tcu::Vec2(-1.0f, -2.7f), tcu::Vec2(-0.5f, float(m_numLayers)+0.5f)));
		m_cases.push_back(FilterCase(m_gridTex,		tcu::Vec2( 0.2f,  0.175f),	tcu::Vec2(-2.0f, -3.7f), tcu::Vec2(-0.5f, float(m_numLayers)+0.5f)));
		m_cases.push_back(FilterCase(m_gridTex,		tcu::Vec2(-0.8f, -2.3f  ),	tcu::Vec2( 0.2f, -0.1f), tcu::Vec2(float(m_numLayers)+0.5f, -0.5f)));

		// Level rounding - only in single-sample configs as multisample configs may produce smooth transition at the middle.
		if (m_context.getRenderTarget().getNumSamples() == 0)
			m_cases.push_back(FilterCase(m_gradientTex,	tcu::Vec2(-2.0f, -1.5f  ),	tcu::Vec2(-0.1f,  0.9f), tcu::Vec2(1.50001f, 1.49999f)));

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

void Texture2DArrayFilteringCase::deinit (void)
{
	delete m_gradientTex;
	delete m_gridTex;

	m_gradientTex	= DE_NULL;
	m_gridTex		= DE_NULL;

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

Texture2DArrayFilteringCase::IterateResult Texture2DArrayFilteringCase::iterate (void)
{
	const glw::Functions&			gl			= m_context.getRenderContext().getFunctions();
	const RandomViewport			viewport	(m_context.getRenderTarget(), TEX3D_VIEWPORT_WIDTH, TEX3D_VIEWPORT_HEIGHT, deStringHash(getName()) ^ deInt32Hash(m_caseNdx));
	const FilterCase&				curCase		= m_cases[m_caseNdx];
	const tcu::TextureFormat		texFmt		= curCase.texture->getRefTexture().getFormat();
	const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFmt);
	const tcu::ScopedLogSection		section		(m_testCtx.getLog(), string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
	ReferenceParams					refParams	(TEXTURETYPE_2D_ARRAY);
	tcu::Surface					rendered	(viewport.width, viewport.height);
	tcu::Vec3						texCoord[4];

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

	// Setup params for reference.
	refParams.sampler		= glu::mapGLSampler(m_wrapS, m_wrapT, 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 << "Approximate lod per axis = " << curCase.lod << ", offset = " << curCase.offset << TestLog::EndMessage;

	{
		const float	lodX	= curCase.lod.x();
		const float	lodY	= curCase.lod.y();
		const float	oX		= curCase.offset.x();
		const float	oY		= curCase.offset.y();
		const float	sX		= deFloatExp2(lodX)*float(viewport.width)	/ float(m_gradientTex->getRefTexture().getWidth());
		const float	sY		= deFloatExp2(lodY)*float(viewport.height)	/ float(m_gradientTex->getRefTexture().getHeight());
		const float	l0		= curCase.layerRange.x();
		const float	l1		= curCase.layerRange.y();

		texCoord[0] = tcu::Vec3(oX,		oY,		l0);
		texCoord[1] = tcu::Vec3(oX,		oY+sY,	l0*0.5f + l1*0.5f);
		texCoord[2] = tcu::Vec3(oX+sX,	oY,		l0*0.5f + l1*0.5f);
		texCoord[3] = tcu::Vec3(oX+sX,	oY+sY,	l1);
	}

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

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

	{
		const bool				isNearestOnly	= m_minFilter == GL_NEAREST && m_magFilter == GL_NEAREST;
		const tcu::PixelFormat	pixelFormat		= m_context.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		= 18;
		lodPrecision.lodBits			= 6;
		lookupPrecision.colorThreshold	= tcu::computeFixedPointThreshold(colorBits) / refParams.colorScale;
		lookupPrecision.coordBits		= tcu::IVec3(20,20,20);
		lookupPrecision.uvwBits			= tcu::IVec3(7,7,0);
		lookupPrecision.colorMask		= getCompareMask(pixelFormat);

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

		if (!isHighQuality)
		{
			// Evaluate against lower precision requirements.
			lodPrecision.lodBits	= 4;
			lookupPrecision.uvwBits	= tcu::IVec3(4,4,0);

			m_testCtx.getLog() << TestLog::Message << "Warning: Verification against high precision requirements failed, trying with lower requirements." << TestLog::EndMessage;

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

			if (!isOk)
			{
				m_testCtx.getLog() << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
			}
			else if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
				m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality filtering result");
		}
	}

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

// 3D filtering

class Texture3DFilteringCase : public TestCase
{
public:
									Texture3DFilteringCase		(Context& context, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 wrapR, deUint32 internalFormat, int width, int height, int depth);
									~Texture3DFilteringCase		(void);

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

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

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

	const deUint32					m_internalFormat;
	const int						m_width;
	const int						m_height;
	const int						m_depth;

	struct FilterCase
	{
		const glu::Texture3D*	texture;
		tcu::Vec3				lod;
		tcu::Vec3				offset;

		FilterCase (void)
			: texture(DE_NULL)
		{
		}

		FilterCase (const glu::Texture3D* tex_, const tcu::Vec3& lod_, const tcu::Vec3& offset_)
			: texture	(tex_)
			, lod		(lod_)
			, offset	(offset_)
		{
		}
	};

	glu::Texture3D*					m_gradientTex;
	glu::Texture3D*					m_gridTex;

	TextureRenderer					m_renderer;

	std::vector<FilterCase>			m_cases;
	int								m_caseNdx;
};

Texture3DFilteringCase::Texture3DFilteringCase (Context& context, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 wrapR, deUint32 internalFormat, int width, int height, int depth)
	: TestCase			(context, name, desc)
	, m_minFilter		(minFilter)
	, m_magFilter		(magFilter)
	, m_wrapS			(wrapS)
	, m_wrapT			(wrapT)
	, m_wrapR			(wrapR)
	, m_internalFormat	(internalFormat)
	, m_width			(width)
	, m_height			(height)
	, m_depth			(depth)
	, m_gradientTex		(DE_NULL)
	, m_gridTex			(DE_NULL)
	, m_renderer		(context.getRenderContext(), context.getTestContext().getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_HIGHP)
	, m_caseNdx			(0)
{
}

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

void Texture3DFilteringCase::init (void)
{
	checkSupport(m_context.getContextInfo(), m_internalFormat);

	try
	{
		const tcu::TextureFormat		texFmt		= glu::mapGLInternalFormat(m_internalFormat);
		const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFmt);
		const tcu::Vec4					cScale		= fmtInfo.valueMax-fmtInfo.valueMin;
		const tcu::Vec4					cBias		= fmtInfo.valueMin;
		const int						numLevels	= deLog2Floor32(de::max(de::max(m_width, m_height), m_depth)) + 1;

		// Create textures.
		m_gradientTex	= new glu::Texture3D(m_context.getRenderContext(), m_internalFormat, m_width, m_height, m_depth);
		m_gridTex		= new glu::Texture3D(m_context.getRenderContext(), m_internalFormat, m_width, m_height, m_depth);

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

			m_gradientTex->getRefTexture().allocLevel(levelNdx);
			tcu::fillWithComponentGradients(m_gradientTex->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_gridTex->getRefTexture().allocLevel(levelNdx);
			tcu::fillWithGrid(m_gridTex->getRefTexture().getLevel(levelNdx), 4, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
		}

		// Upload.
		m_gradientTex->upload();
		m_gridTex->upload();

		// Test cases
		m_cases.push_back(FilterCase(m_gradientTex,	tcu::Vec3(1.5f, 2.8f, 1.0f),	tcu::Vec3(-1.0f, -2.7f, -2.275f)));
		m_cases.push_back(FilterCase(m_gradientTex,	tcu::Vec3(-2.0f, -1.5f, -1.8f),	tcu::Vec3(-0.1f, 0.9f, -0.25f)));
		m_cases.push_back(FilterCase(m_gridTex,		tcu::Vec3(0.2f, 0.175f, 0.3f),	tcu::Vec3(-2.0f, -3.7f, -1.825f)));
		m_cases.push_back(FilterCase(m_gridTex,		tcu::Vec3(-0.8f, -2.3f, -2.5f),	tcu::Vec3(0.2f, -0.1f, 1.325f)));

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

void Texture3DFilteringCase::deinit (void)
{
	delete m_gradientTex;
	delete m_gridTex;

	m_gradientTex	= DE_NULL;
	m_gridTex		= DE_NULL;

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

Texture3DFilteringCase::IterateResult Texture3DFilteringCase::iterate (void)
{
	const glw::Functions&			gl			= m_context.getRenderContext().getFunctions();
	const RandomViewport			viewport	(m_context.getRenderTarget(), TEX3D_VIEWPORT_WIDTH, TEX3D_VIEWPORT_HEIGHT, deStringHash(getName()) ^ deInt32Hash(m_caseNdx));
	const FilterCase&				curCase		= m_cases[m_caseNdx];
	const tcu::TextureFormat		texFmt		= curCase.texture->getRefTexture().getFormat();
	const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFmt);
	const tcu::ScopedLogSection		section		(m_testCtx.getLog(), string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
	ReferenceParams					refParams	(TEXTURETYPE_3D);
	tcu::Surface					rendered	(viewport.width, viewport.height);
	tcu::Vec3						texCoord[4];

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

	// Setup params for reference.
	refParams.sampler		= glu::mapGLSampler(m_wrapS, m_wrapT, m_wrapR, 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 << "Approximate lod per axis = " << curCase.lod << ", offset = " << curCase.offset << TestLog::EndMessage;

	{
		const float	lodX	= curCase.lod.x();
		const float	lodY	= curCase.lod.y();
		const float	lodZ	= curCase.lod.z();
		const float	oX		= curCase.offset.x();
		const float	oY		= curCase.offset.y();
		const float oZ		= curCase.offset.z();
		const float	sX		= deFloatExp2(lodX)*float(viewport.width)							/ float(m_gradientTex->getRefTexture().getWidth());
		const float	sY		= deFloatExp2(lodY)*float(viewport.height)							/ float(m_gradientTex->getRefTexture().getHeight());
		const float	sZ		= deFloatExp2(lodZ)*float(de::max(viewport.width, viewport.height))	/ float(m_gradientTex->getRefTexture().getDepth());

		texCoord[0] = tcu::Vec3(oX,		oY,		oZ);
		texCoord[1] = tcu::Vec3(oX,		oY+sY,	oZ + sZ*0.5f);
		texCoord[2] = tcu::Vec3(oX+sX,	oY,		oZ + sZ*0.5f);
		texCoord[3] = tcu::Vec3(oX+sX,	oY+sY,	oZ + sZ);
	}

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

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

	{
		const bool				isNearestOnly	= m_minFilter == GL_NEAREST && m_magFilter == GL_NEAREST;
		const tcu::PixelFormat	pixelFormat		= m_context.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		= 18;
		lodPrecision.lodBits			= 6;
		lookupPrecision.colorThreshold	= tcu::computeFixedPointThreshold(colorBits) / refParams.colorScale;
		lookupPrecision.coordBits		= tcu::IVec3(20,20,20);
		lookupPrecision.uvwBits			= tcu::IVec3(7,7,7);
		lookupPrecision.colorMask		= getCompareMask(pixelFormat);

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

		if (!isHighQuality)
		{
			// Evaluate against lower precision requirements.
			lodPrecision.lodBits	= 4;
			lookupPrecision.uvwBits	= tcu::IVec3(4,4,4);

			m_testCtx.getLog() << TestLog::Message << "Warning: Verification against high precision requirements failed, trying with lower requirements." << TestLog::EndMessage;

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

			if (!isOk)
			{
				m_testCtx.getLog() << TestLog::Message << "ERROR: Verification against low precision requirements failed, failing test case." << TestLog::EndMessage;
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
			}
			else if (m_testCtx.getTestResult() == QP_TEST_RESULT_PASS)
				m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Low-quality filtering result");
		}
	}

	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)
{
	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
	{
		int width;
		int height;
	} sizes2D[] =
	{
		{   4,	  8 },
		{  32,	 64 },
		{ 128,	128	},
		{   3,	  7 },
		{  31,	 55 },
		{ 127,	 99 }
	};

	static const struct
	{
		int width;
		int height;
	} sizesCube[] =
	{
		{   8,   8 },
		{  64,  64 },
		{ 128, 128 },
		{   7,   7 },
		{  63,  63 }
	};

	static const struct
	{
		int width;
		int height;
		int numLayers;
	} sizes2DArray[] =
	{
		{   4,   8,   8 },
		{  32,  64,  16 },
		{ 128,  32,  64 },
		{   3,   7,   5 },
		{  63,  63,  63 }
	};

	static const struct
	{
		int width;
		int height;
		int depth;
	} sizes3D[] =
	{
		{   4,   8,   8 },
		{  32,  64,  16 },
		{ 128,  32,  64 },
		{   3,   7,   5 },
		{  63,  63,  63 }
	};

	static const struct
	{
		const char*		name;
		deUint32		format;
	} filterableFormatsByType[] =
	{
		{ "rgba16f",		GL_RGBA16F			},
		{ "r11f_g11f_b10f",	GL_R11F_G11F_B10F	},
		{ "rgb9_e5",		GL_RGB9_E5			},
		{ "rgba8",			GL_RGBA8			},
		{ "rgba8_snorm",	GL_RGBA8_SNORM		},
		{ "rgb565",			GL_RGB565			},
		{ "rgba4",			GL_RGBA4			},
		{ "rgb5_a1",		GL_RGB5_A1			},
		{ "srgb8_alpha8",	GL_SRGB8_ALPHA8		},
		{ "srgb_r8",		GL_SR8_EXT			},
		{ "rgb10_a2",		GL_RGB10_A2			}
	};

	// 2D texture filtering.
	{
		tcu::TestCaseGroup* group2D = new tcu::TestCaseGroup(m_testCtx, "2d", "2D Texture Filtering");
		addChild(group2D);

		// Formats.
		tcu::TestCaseGroup* formatsGroup = new tcu::TestCaseGroup(m_testCtx, "formats", "2D Texture Formats");
		group2D->addChild(formatsGroup);
		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
		{
			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
			{
				deUint32		minFilter	= minFilterModes[filterNdx].mode;
				const char*		filterName	= minFilterModes[filterNdx].name;
				deUint32		format		= filterableFormatsByType[fmtNdx].format;
				const char*		formatName	= filterableFormatsByType[fmtNdx].name;
				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
				string			name		= string(formatName) + "_" + filterName;
				deUint32		wrapS		= GL_REPEAT;
				deUint32		wrapT		= GL_REPEAT;
				int				width		= 64;
				int				height		= 64;

				formatsGroup->addChild(new Texture2DFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
																  name.c_str(), "",
																  minFilter, magFilter,
																  wrapS, wrapT,
																  format,
																  width, height));
			}
		}

		// ETC1 format.
		{
			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 (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
			{
				deUint32		minFilter	= minFilterModes[filterNdx].mode;
				const char*		filterName	= minFilterModes[filterNdx].name;
				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
				string			name		= string("etc1_rgb8_") + filterName;
				deUint32		wrapS		= GL_REPEAT;
				deUint32		wrapT		= GL_REPEAT;

				formatsGroup->addChild(new Texture2DFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
																  name.c_str(), "",
																  minFilter, magFilter,
																  wrapS, wrapT,
																  filenames));
			}
		}

		// Sizes.
		tcu::TestCaseGroup* sizesGroup = new tcu::TestCaseGroup(m_testCtx, "sizes", "Texture Sizes");
		group2D->addChild(sizesGroup);
		for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes2D); sizeNdx++)
		{
			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
			{
				deUint32		minFilter	= minFilterModes[filterNdx].mode;
				const char*		filterName	= minFilterModes[filterNdx].name;
				deUint32		format		= GL_RGBA8;
				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
				deUint32		wrapS		= GL_REPEAT;
				deUint32		wrapT		= GL_REPEAT;
				int				width		= sizes2D[sizeNdx].width;
				int				height		= sizes2D[sizeNdx].height;
				string			name		= de::toString(width) + "x" + de::toString(height) + "_" + filterName;

				sizesGroup->addChild(new Texture2DFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
																name.c_str(), "",
																minFilter, magFilter,
																wrapS, wrapT,
																format,
																width, height));
			}
		}

		// Wrap modes.
		tcu::TestCaseGroup* combinationsGroup = new tcu::TestCaseGroup(m_testCtx, "combinations", "Filter and wrap mode combinations");
		group2D->addChild(combinationsGroup);
		for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); minFilterNdx++)
		{
			for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilterModes); magFilterNdx++)
			{
				for (int wrapSNdx = 0; wrapSNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapSNdx++)
				{
					for (int wrapTNdx = 0; wrapTNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapTNdx++)
					{
						deUint32		minFilter	= minFilterModes[minFilterNdx].mode;
						deUint32		magFilter	= magFilterModes[magFilterNdx].mode;
						deUint32		format		= GL_RGBA8;
						deUint32		wrapS		= wrapModes[wrapSNdx].mode;
						deUint32		wrapT		= wrapModes[wrapTNdx].mode;
						int				width		= 63;
						int				height		= 57;
						string			name		= string(minFilterModes[minFilterNdx].name) + "_" + magFilterModes[magFilterNdx].name + "_" + wrapModes[wrapSNdx].name + "_" + wrapModes[wrapTNdx].name;

						combinationsGroup->addChild(new Texture2DFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
																			   name.c_str(), "",
																			   minFilter, magFilter,
																			   wrapS, wrapT,
																			   format,
																			   width, height));
					}
				}
			}
		}
	}

	// Cube map texture filtering.
	{
		tcu::TestCaseGroup* groupCube = new tcu::TestCaseGroup(m_testCtx, "cube", "Cube Map Texture Filtering");
		addChild(groupCube);

		// Formats.
		tcu::TestCaseGroup* formatsGroup = new tcu::TestCaseGroup(m_testCtx, "formats", "2D Texture Formats");
		groupCube->addChild(formatsGroup);
		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
		{
			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
			{
				deUint32		minFilter	= minFilterModes[filterNdx].mode;
				const char*		filterName	= minFilterModes[filterNdx].name;
				deUint32		format		= filterableFormatsByType[fmtNdx].format;
				const char*		formatName	= filterableFormatsByType[fmtNdx].name;
				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
				string			name		= string(formatName) + "_" + filterName;
				deUint32		wrapS		= GL_REPEAT;
				deUint32		wrapT		= GL_REPEAT;
				int				width		= 64;
				int				height		= 64;

				formatsGroup->addChild(new TextureCubeFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
																	name.c_str(), "",
																	minFilter, magFilter,
																	wrapS, wrapT,
																	false /* always sample exterior as well */,
																	format,
																	width, height));
			}
		}

		// ETC1 format.
		{
			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 (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
			{
				deUint32		minFilter	= minFilterModes[filterNdx].mode;
				const char*		filterName	= minFilterModes[filterNdx].name;
				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
				string			name		= string("etc1_rgb8_") + filterName;
				deUint32		wrapS		= GL_REPEAT;
				deUint32		wrapT		= GL_REPEAT;

				formatsGroup->addChild(new TextureCubeFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
																	name.c_str(), "",
																	minFilter, magFilter,
																	wrapS, wrapT,
																	false /* always sample exterior as well */,
																	filenames));
			}
		}

		// Sizes.
		tcu::TestCaseGroup* sizesGroup = new tcu::TestCaseGroup(m_testCtx, "sizes", "Texture Sizes");
		groupCube->addChild(sizesGroup);
		for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizesCube); sizeNdx++)
		{
			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
			{
				deUint32		minFilter	= minFilterModes[filterNdx].mode;
				const char*		filterName	= minFilterModes[filterNdx].name;
				deUint32		format		= GL_RGBA8;
				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
				deUint32		wrapS		= GL_REPEAT;
				deUint32		wrapT		= GL_REPEAT;
				int				width		= sizesCube[sizeNdx].width;
				int				height		= sizesCube[sizeNdx].height;
				string			name		= de::toString(width) + "x" + de::toString(height) + "_" + filterName;

				sizesGroup->addChild(new TextureCubeFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
																  name.c_str(), "",
																  minFilter, magFilter,
																  wrapS, wrapT,
																  false,
																  format,
																  width, height));
			}
		}

		// Filter/wrap mode combinations.
		tcu::TestCaseGroup* combinationsGroup = new tcu::TestCaseGroup(m_testCtx, "combinations", "Filter and wrap mode combinations");
		groupCube->addChild(combinationsGroup);
		for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); minFilterNdx++)
		{
			for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilterModes); magFilterNdx++)
			{
				for (int wrapSNdx = 0; wrapSNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapSNdx++)
				{
					for (int wrapTNdx = 0; wrapTNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapTNdx++)
					{
						deUint32		minFilter	= minFilterModes[minFilterNdx].mode;
						deUint32		magFilter	= magFilterModes[magFilterNdx].mode;
						deUint32		format		= GL_RGBA8;
						deUint32		wrapS		= wrapModes[wrapSNdx].mode;
						deUint32		wrapT		= wrapModes[wrapTNdx].mode;
						int				width		= 63;
						int				height		= 63;
						string			name		= string(minFilterModes[minFilterNdx].name) + "_" + magFilterModes[magFilterNdx].name + "_" + wrapModes[wrapSNdx].name + "_" + wrapModes[wrapTNdx].name;

						combinationsGroup->addChild(new TextureCubeFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
																				 name.c_str(), "",
																				 minFilter, magFilter,
																				 wrapS, wrapT,
																				 false,
																				 format,
																				 width, height));
					}
				}
			}
		}

		// Cases with no visible cube edges.
		tcu::TestCaseGroup* onlyFaceInteriorGroup = new tcu::TestCaseGroup(m_testCtx, "no_edges_visible", "Don't sample anywhere near a face's edges");
		groupCube->addChild(onlyFaceInteriorGroup);

		for (int isLinearI = 0; isLinearI <= 1; isLinearI++)
		{
			bool		isLinear	= isLinearI != 0;
			deUint32	filter		= isLinear ? GL_LINEAR : GL_NEAREST;

			onlyFaceInteriorGroup->addChild(new TextureCubeFilteringCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(),
																		 isLinear ? "linear" : "nearest", "",
																		 filter, filter,
																		 GL_REPEAT, GL_REPEAT,
																		 true,
																		 GL_RGBA8,
																		 63, 63));
		}
	}

	// 2D array texture filtering.
	{
		tcu::TestCaseGroup* const group2DArray = new tcu::TestCaseGroup(m_testCtx, "2d_array", "2D Array Texture Filtering");
		addChild(group2DArray);

		// Formats.
		tcu::TestCaseGroup* const formatsGroup = new tcu::TestCaseGroup(m_testCtx, "formats", "2D Array Texture Formats");
		group2DArray->addChild(formatsGroup);
		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
		{
			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
			{
				deUint32		minFilter	= minFilterModes[filterNdx].mode;
				const char*		filterName	= minFilterModes[filterNdx].name;
				deUint32		format		= filterableFormatsByType[fmtNdx].format;
				const char*		formatName	= filterableFormatsByType[fmtNdx].name;
				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
				string			name		= string(formatName) + "_" + filterName;
				deUint32		wrapS		= GL_REPEAT;
				deUint32		wrapT		= GL_REPEAT;
				int				width		= 128;
				int				height		= 128;
				int				numLayers	= 8;

				formatsGroup->addChild(new Texture2DArrayFilteringCase(m_context,
																	   name.c_str(), "",
																	   minFilter, magFilter,
																	   wrapS, wrapT,
																	   format,
																	   width, height, numLayers));
			}
		}

		// Sizes.
		tcu::TestCaseGroup* sizesGroup = new tcu::TestCaseGroup(m_testCtx, "sizes", "Texture Sizes");
		group2DArray->addChild(sizesGroup);
		for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes2DArray); sizeNdx++)
		{
			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
			{
				deUint32		minFilter	= minFilterModes[filterNdx].mode;
				const char*		filterName	= minFilterModes[filterNdx].name;
				deUint32		format		= GL_RGBA8;
				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
				deUint32		wrapS		= GL_REPEAT;
				deUint32		wrapT		= GL_REPEAT;
				int				width		= sizes2DArray[sizeNdx].width;
				int				height		= sizes2DArray[sizeNdx].height;
				int				numLayers	= sizes2DArray[sizeNdx].numLayers;
				string			name		= de::toString(width) + "x" + de::toString(height) + "x" + de::toString(numLayers) + "_" + filterName;

				sizesGroup->addChild(new Texture2DArrayFilteringCase(m_context,
																	 name.c_str(), "",
																	 minFilter, magFilter,
																	 wrapS, wrapT,
																	 format,
																	 width, height, numLayers));
			}
		}

		// Wrap modes.
		tcu::TestCaseGroup* const combinationsGroup = new tcu::TestCaseGroup(m_testCtx, "combinations", "Filter and wrap mode combinations");
		group2DArray->addChild(combinationsGroup);
		for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); minFilterNdx++)
		{
			for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilterModes); magFilterNdx++)
			{
				for (int wrapSNdx = 0; wrapSNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapSNdx++)
				{
					for (int wrapTNdx = 0; wrapTNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapTNdx++)
					{
						deUint32		minFilter	= minFilterModes[minFilterNdx].mode;
						deUint32		magFilter	= magFilterModes[magFilterNdx].mode;
						deUint32		format		= GL_RGBA8;
						deUint32		wrapS		= wrapModes[wrapSNdx].mode;
						deUint32		wrapT		= wrapModes[wrapTNdx].mode;
						int				width		= 123;
						int				height		= 107;
						int				numLayers	= 7;
						string			name		= string(minFilterModes[minFilterNdx].name) + "_" + magFilterModes[magFilterNdx].name + "_" + wrapModes[wrapSNdx].name + "_" + wrapModes[wrapTNdx].name;

						combinationsGroup->addChild(new Texture2DArrayFilteringCase(m_context,
																					name.c_str(), "",
																					minFilter, magFilter,
																					wrapS, wrapT,
																					format,
																					width, height, numLayers));
					}
				}
			}
		}
	}

	// 3D texture filtering.
	{
		tcu::TestCaseGroup* group3D = new tcu::TestCaseGroup(m_testCtx, "3d", "3D Texture Filtering");
		addChild(group3D);

		// Formats.
		tcu::TestCaseGroup* formatsGroup = new tcu::TestCaseGroup(m_testCtx, "formats", "3D Texture Formats");
		group3D->addChild(formatsGroup);
		for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(filterableFormatsByType); fmtNdx++)
		{
			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
			{
				deUint32		minFilter	= minFilterModes[filterNdx].mode;
				const char*		filterName	= minFilterModes[filterNdx].name;
				deUint32		format		= filterableFormatsByType[fmtNdx].format;
				const char*		formatName	= filterableFormatsByType[fmtNdx].name;
				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
				string			name		= string(formatName) + "_" + filterName;
				deUint32		wrapS		= GL_REPEAT;
				deUint32		wrapT		= GL_REPEAT;
				deUint32		wrapR		= GL_REPEAT;
				int				width		= 64;
				int				height		= 64;
				int				depth		= 64;

				formatsGroup->addChild(new Texture3DFilteringCase(m_context,
																  name.c_str(), "",
																  minFilter, magFilter,
																  wrapS, wrapT, wrapR,
																  format,
																  width, height, depth));
			}
		}

		// Sizes.
		tcu::TestCaseGroup* sizesGroup = new tcu::TestCaseGroup(m_testCtx, "sizes", "Texture Sizes");
		group3D->addChild(sizesGroup);
		for (int sizeNdx = 0; sizeNdx < DE_LENGTH_OF_ARRAY(sizes3D); sizeNdx++)
		{
			for (int filterNdx = 0; filterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); filterNdx++)
			{
				deUint32		minFilter	= minFilterModes[filterNdx].mode;
				const char*		filterName	= minFilterModes[filterNdx].name;
				deUint32		format		= GL_RGBA8;
				bool			isMipmap	= minFilter != GL_NEAREST && minFilter != GL_LINEAR;
				deUint32		magFilter	= isMipmap ? GL_LINEAR : minFilter;
				deUint32		wrapS		= GL_REPEAT;
				deUint32		wrapT		= GL_REPEAT;
				deUint32		wrapR		= GL_REPEAT;
				int				width		= sizes3D[sizeNdx].width;
				int				height		= sizes3D[sizeNdx].height;
				int				depth		= sizes3D[sizeNdx].depth;
				string			name		= de::toString(width) + "x" + de::toString(height) + "x" + de::toString(depth) + "_" + filterName;

				sizesGroup->addChild(new Texture3DFilteringCase(m_context,
																name.c_str(), "",
																minFilter, magFilter,
																wrapS, wrapT, wrapR,
																format,
																width, height, depth));
			}
		}

		// Wrap modes.
		tcu::TestCaseGroup* combinationsGroup = new tcu::TestCaseGroup(m_testCtx, "combinations", "Filter and wrap mode combinations");
		group3D->addChild(combinationsGroup);
		for (int minFilterNdx = 0; minFilterNdx < DE_LENGTH_OF_ARRAY(minFilterModes); minFilterNdx++)
		{
			for (int magFilterNdx = 0; magFilterNdx < DE_LENGTH_OF_ARRAY(magFilterModes); magFilterNdx++)
			{
				for (int wrapSNdx = 0; wrapSNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapSNdx++)
				{
					for (int wrapTNdx = 0; wrapTNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapTNdx++)
					{
						for (int wrapRNdx = 0; wrapRNdx < DE_LENGTH_OF_ARRAY(wrapModes); wrapRNdx++)
						{
							deUint32		minFilter	= minFilterModes[minFilterNdx].mode;
							deUint32		magFilter	= magFilterModes[magFilterNdx].mode;
							deUint32		format		= GL_RGBA8;
							deUint32		wrapS		= wrapModes[wrapSNdx].mode;
							deUint32		wrapT		= wrapModes[wrapTNdx].mode;
							deUint32		wrapR		= wrapModes[wrapRNdx].mode;
							int				width		= 63;
							int				height		= 57;
							int				depth		= 67;
							string			name		= string(minFilterModes[minFilterNdx].name) + "_" + magFilterModes[magFilterNdx].name + "_" + wrapModes[wrapSNdx].name + "_" + wrapModes[wrapTNdx].name + "_" + wrapModes[wrapRNdx].name;

							combinationsGroup->addChild(new Texture3DFilteringCase(m_context,
																				   name.c_str(), "",
																				   minFilter, magFilter,
																				   wrapS, wrapT, wrapR,
																				   format,
																				   width, height, depth));
						}
					}
				}
			}
		}
	}
}

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