/*-------------------------------------------------------------------------
 * 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_R8 is not supported.");

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

} // anonymous

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			},
		{ "srgb_rg8",		GL_SRG8_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
