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

#include "es3aTextureFilteringTests.hpp"
#include "glsTextureTestUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "gluTexture.hpp"
#include "gluTextureUtil.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuImageCompare.hpp"
#include "deStringUtil.hpp"
#include "deString.h"

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

namespace deqp
{
namespace gles3
{
namespace Accuracy
{

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

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;

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

	deUint32					m_internalFormat;
	int							m_width;
	int							m_height;

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

	std::vector<glu::Texture2D*>	m_textures;
	TextureRenderer					m_renderer;
};

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, tcu::NODETYPE_ACCURACY, 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)
{
}

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, tcu::NODETYPE_ACCURACY, 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_100_ES, glu::PRECISION_HIGHP)
{
}

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

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

			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 gradient texture.
			for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
			{
				tcu::Vec4 gMin = tcu::Vec4(-0.5f, -0.5f, -0.5f, 2.0f)*cScale + cBias;
				tcu::Vec4 gMax = tcu::Vec4( 1.0f,  1.0f,  1.0f, 0.0f)*cScale + cBias;

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

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

				m_textures[1]->getRefTexture().allocLevel(levelNdx);
				tcu::fillWithGrid(m_textures[1]->getRefTexture().getLevel(levelNdx), 4, 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();
		}
	}
	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();
}

Texture2DFilteringCase::IterateResult Texture2DFilteringCase::iterate (void)
{
	const glw::Functions&		gl					= m_renderCtx.getFunctions();
	TestLog&					log					= m_testCtx.getLog();
	const int					defViewportWidth	= 256;
	const int					defViewportHeight	= 256;
	RandomViewport				viewport			(m_renderCtx.getRenderTarget(), defViewportWidth, defViewportHeight, deStringHash(getName()));
	tcu::Surface				renderedFrame		(viewport.width, viewport.height);
	tcu::Surface				referenceFrame		(viewport.width, viewport.height);
	const tcu::TextureFormat&	texFmt				= m_textures[0]->getRefTexture().getFormat();
	tcu::TextureFormatInfo		fmtInfo				= tcu::getTextureFormatInfo(texFmt);
	ReferenceParams				refParams			(TEXTURETYPE_2D);
	vector<float>				texCoord;

	// Accuracy measurements are off unless viewport size is 256x256
	if (viewport.width < defViewportWidth || viewport.height < defViewportHeight)
		throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);

	// Viewport is divided into 4 sections.
	int				leftWidth			= viewport.width / 2;
	int				rightWidth			= viewport.width - leftWidth;
	int				bottomHeight		= viewport.height / 2;
	int				topHeight			= viewport.height - bottomHeight;

	int				curTexNdx			= 0;

	// Use unit 0.
	gl.activeTexture(GL_TEXTURE0);

	// Bind gradient texture and setup sampler parameters.
	gl.bindTexture(GL_TEXTURE_2D, m_textures[curTexNdx]->getGLTexture());
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	m_magFilter);

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

	// Bottom left: Minification
	{
		gl.viewport(viewport.x, viewport.y, leftWidth, bottomHeight);

		computeQuadTexCoord2D(texCoord, tcu::Vec2(-4.0f, -4.5f), tcu::Vec2(4.0f, 2.5f));

		m_renderer.renderQuad(0, &texCoord[0], refParams);
		sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), 0, 0, leftWidth, bottomHeight),
					  m_textures[curTexNdx]->getRefTexture(), &texCoord[0], refParams);
	}

	// Bottom right: Magnification
	{
		gl.viewport(viewport.x+leftWidth, viewport.y, rightWidth, bottomHeight);

		computeQuadTexCoord2D(texCoord, tcu::Vec2(-0.5f, 0.75f), tcu::Vec2(0.25f, 1.25f));

		m_renderer.renderQuad(0, &texCoord[0], refParams);
		sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), leftWidth, 0, rightWidth, bottomHeight),
					  m_textures[curTexNdx]->getRefTexture(), &texCoord[0], refParams);
	}

	if (m_textures.size() >= 2)
	{
		curTexNdx += 1;

		// Setup second texture.
		gl.bindTexture(GL_TEXTURE_2D, m_textures[curTexNdx]->getGLTexture());
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	m_magFilter);
	}

	// Top left: Minification
	// \note Minification is chosen so that 0.0 < lod <= 0.5. This way special minification threshold rule will be triggered.
	{
		gl.viewport(viewport.x, viewport.y+bottomHeight, leftWidth, topHeight);

		float	sMin		= -0.5f;
		float	tMin		= -0.2f;
		float	sRange		= ((float)leftWidth * 1.2f) / (float)m_textures[curTexNdx]->getRefTexture().getWidth();
		float	tRange		= ((float)topHeight * 1.1f) / (float)m_textures[curTexNdx]->getRefTexture().getHeight();

		computeQuadTexCoord2D(texCoord, tcu::Vec2(sMin, tMin), tcu::Vec2(sMin+sRange, tMin+tRange));

		m_renderer.renderQuad(0, &texCoord[0], refParams);
		sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), 0, bottomHeight, leftWidth, topHeight),
					  m_textures[curTexNdx]->getRefTexture(), &texCoord[0], refParams);
	}

	// Top right: Magnification
	{
		gl.viewport(viewport.x+leftWidth, viewport.y+bottomHeight, rightWidth, topHeight);

		computeQuadTexCoord2D(texCoord, tcu::Vec2(-0.5f, 0.75f), tcu::Vec2(0.25f, 1.25f));

		m_renderer.renderQuad(0, &texCoord[0], refParams);
		sampleTexture(tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), leftWidth, bottomHeight, rightWidth, topHeight),
					  m_textures[curTexNdx]->getRefTexture(), &texCoord[0], refParams);
	}

	// Read result.
	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());

	// Compare and log.
	{
		const int	bestScoreDiff	= 16;
		const int	worstScoreDiff	= 3200;

		int score = measureAccuracy(log, referenceFrame, renderedFrame, bestScoreDiff, worstScoreDiff);
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::toString(score).c_str());
	}

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

	deUint32					m_minFilter;
	deUint32					m_magFilter;
	deUint32					m_wrapS;
	deUint32					m_wrapT;
	bool						m_onlySampleFaceInterior; //!< If true, we avoid sampling anywhere near a face's edges.

	deUint32					m_internalFormat;
	int							m_width;
	int							m_height;

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

	std::vector<glu::TextureCube*>	m_textures;
	TextureRenderer					m_renderer;
};

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, tcu::NODETYPE_ACCURACY, 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)
{
}

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, tcu::NODETYPE_ACCURACY, 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)
{
}

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

void TextureCubeFilteringCase::init (void)
{
	try
	{
		if (!m_filenames.empty())
		{
			m_textures.reserve(1);
			m_textures.push_back(glu::TextureCube::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size() / 6, m_filenames));
		}
		else
		{
			m_textures.reserve(2);
			DE_ASSERT(m_width == m_height);
			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(-1.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative x
				{ tcu::Vec4( 0.0f, -1.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive x
				{ tcu::Vec4(-1.0f,  0.0f, -1.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative y
				{ tcu::Vec4(-1.0f, -1.0f,  0.0f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive y
				{ tcu::Vec4(-1.0f, -1.0f, -1.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f) }, // negative z
				{ tcu::Vec4( 0.0f,  0.0f,  0.0f, 2.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);
				}
			}

			if (m_magFilter == GL_LINEAR || m_minFilter == GL_LINEAR || m_minFilter == GL_LINEAR_MIPMAP_NEAREST || m_minFilter == GL_LINEAR_MIPMAP_LINEAR)
			{
				// Using seamless linear cube map filtering - set all corner texels to the same color, because cube corner sampling in this case is not very well defined by the spec.
				// \todo Probably should also do this for cases where textures are loaded from files.

				for (int texNdx = 0; texNdx < (int)m_textures.size(); texNdx++)
				{
					for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
					{
						for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
						{
							static const tcu::Vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
							tcu::PixelBufferAccess access = m_textures[texNdx]->getRefTexture().getLevelFace(levelNdx, (tcu::CubeFace)face);

							access.setPixel(color, 0,					0);
							access.setPixel(color, access.getWidth()-1,	0);
							access.setPixel(color, 0,					access.getHeight()-1);
							access.setPixel(color, access.getWidth()-1,	access.getHeight()-1);
						}
					}
				}
			}

			// Upload.
			for (std::vector<glu::TextureCube*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
				(*i)->upload();
		}
	}
	catch (const std::exception&)
	{
		// 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();
}

static void renderFaces (
	const glw::Functions&		gl,
	const tcu::SurfaceAccess&	dstRef,
	const tcu::TextureCube&		refTexture,
	const ReferenceParams&		params,
	TextureRenderer&			renderer,
	int							x,
	int							y,
	int							width,
	int							height,
	const tcu::Vec2&			bottomLeft,
	const tcu::Vec2&			topRight,
	const tcu::Vec2&			texCoordTopRightFactor)
{
	DE_ASSERT(width == dstRef.getWidth() && height == dstRef.getHeight());

	vector<float> texCoord;

	DE_STATIC_ASSERT(tcu::CUBEFACE_LAST == 6);
	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
	{
		bool	isRightmost		= (face == 2) || (face == 5);
		bool	isTop			= face >= 3;
		int		curX			= (face % 3) * (width  / 3);
		int		curY			= (face / 3) * (height / 2);
		int		curW			= isRightmost	? (width-curX)	: (width	/ 3);
		int		curH			= isTop			? (height-curY)	: (height	/ 2);

		computeQuadTexCoordCube(texCoord, (tcu::CubeFace)face, bottomLeft, topRight);

		{
			// Move the top and right edges of the texture coord quad. This is useful when we want a cube edge visible.
			int texCoordSRow = face == tcu::CUBEFACE_NEGATIVE_X || face == tcu::CUBEFACE_POSITIVE_X ? 2 : 0;
			int texCoordTRow = face == tcu::CUBEFACE_NEGATIVE_Y || face == tcu::CUBEFACE_POSITIVE_Y ? 2 : 1;
			texCoord[6 + texCoordSRow] *= texCoordTopRightFactor.x();
			texCoord[9 + texCoordSRow] *= texCoordTopRightFactor.x();
			texCoord[3 + texCoordTRow] *= texCoordTopRightFactor.y();
			texCoord[9 + texCoordTRow] *= texCoordTopRightFactor.y();
		}

		gl.viewport(x+curX, y+curY, curW, curH);

		renderer.renderQuad(0, &texCoord[0], params);

		sampleTexture(tcu::SurfaceAccess(dstRef, curX, curY, curW, curH), refTexture, &texCoord[0], params);
	}

	GLU_EXPECT_NO_ERROR(gl.getError(), "Post render");
}

TextureCubeFilteringCase::IterateResult TextureCubeFilteringCase::iterate (void)
{
	const glw::Functions&		gl					= m_renderCtx.getFunctions();
	TestLog&					log					= m_testCtx.getLog();
	const int					cellSize			= 28;
	const int					defViewportWidth	= cellSize*6;
	const int					defViewportHeight	= cellSize*4;
	RandomViewport				viewport			(m_renderCtx.getRenderTarget(), cellSize*6, cellSize*4, deStringHash(getName()));
	tcu::Surface				renderedFrame		(viewport.width, viewport.height);
	tcu::Surface				referenceFrame		(viewport.width, viewport.height);
	ReferenceParams				sampleParams		(TEXTURETYPE_CUBE);
	const tcu::TextureFormat&	texFmt				= m_textures[0]->getRefTexture().getFormat();
	tcu::TextureFormatInfo		fmtInfo				= tcu::getTextureFormatInfo(texFmt);

	// Accuracy measurements are off unless viewport size is exactly as expected.
	if (getNodeType() == tcu::NODETYPE_ACCURACY && (viewport.width < defViewportWidth || viewport.height < defViewportHeight))
		throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);

	// Viewport is divided into 4 sections.
	int				leftWidth			= viewport.width / 2;
	int				rightWidth			= viewport.width - leftWidth;
	int				bottomHeight		= viewport.height / 2;
	int				topHeight			= viewport.height - bottomHeight;

	int				curTexNdx			= 0;

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

	// Use unit 0.
	gl.activeTexture(GL_TEXTURE0);

	// Setup gradient texture.
	gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_textures[curTexNdx]->getGLTexture());
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		m_wrapS);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		m_wrapT);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	m_minFilter);
	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	m_magFilter);

	// Bottom left: Minification
	renderFaces(gl,
				tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), 0, 0, leftWidth, bottomHeight),
				m_textures[curTexNdx]->getRefTexture(), sampleParams,
				m_renderer,
				viewport.x, viewport.y, leftWidth, bottomHeight,
				m_onlySampleFaceInterior ? tcu::Vec2(-0.81f, -0.81f) : tcu::Vec2(-0.975f, -0.975f),
				m_onlySampleFaceInterior ? tcu::Vec2( 0.8f,  0.8f) : tcu::Vec2( 0.975f,  0.975f),
				!m_onlySampleFaceInterior ? tcu::Vec2(1.3f, 1.25f) : tcu::Vec2(1.0f, 1.0f));

	// Bottom right: Magnification
	renderFaces(gl,
				tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), leftWidth, 0, rightWidth, bottomHeight),
				m_textures[curTexNdx]->getRefTexture(), sampleParams,
				m_renderer,
				viewport.x+leftWidth, viewport.y, rightWidth, bottomHeight,
				tcu::Vec2(0.5f, 0.65f), m_onlySampleFaceInterior ? tcu::Vec2(0.8f, 0.8f) : tcu::Vec2(0.975f, 0.975f),
				!m_onlySampleFaceInterior ? tcu::Vec2(1.1f, 1.06f) : tcu::Vec2(1.0f, 1.0f));

	if (m_textures.size() >= 2)
	{
		curTexNdx += 1;

		// Setup second texture.
		gl.bindTexture(GL_TEXTURE_CUBE_MAP, m_textures[curTexNdx]->getGLTexture());
		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		m_wrapS);
		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		m_wrapT);
		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	m_minFilter);
		gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	m_magFilter);
	}

	// Top left: Minification
	renderFaces(gl,
				tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), 0, bottomHeight, leftWidth, topHeight),
				m_textures[curTexNdx]->getRefTexture(), sampleParams,
				m_renderer,
				viewport.x, viewport.y+bottomHeight, leftWidth, topHeight,
				m_onlySampleFaceInterior ? tcu::Vec2(-0.81f, -0.81f) : tcu::Vec2(-0.975f, -0.975f),
				m_onlySampleFaceInterior ? tcu::Vec2( 0.8f,  0.8f) : tcu::Vec2( 0.975f,  0.975f),
				!m_onlySampleFaceInterior ? tcu::Vec2(1.3f, 1.25f) : tcu::Vec2(1.0f, 1.0f));

	// Top right: Magnification
	renderFaces(gl,
				tcu::SurfaceAccess(referenceFrame, m_renderCtx.getRenderTarget().getPixelFormat(), leftWidth, bottomHeight, rightWidth, topHeight),
				m_textures[curTexNdx]->getRefTexture(), sampleParams,
				m_renderer,
				viewport.x+leftWidth, viewport.y+bottomHeight, rightWidth, topHeight,
				tcu::Vec2(0.5f, -0.65f), m_onlySampleFaceInterior ? tcu::Vec2(0.8f, -0.8f) : tcu::Vec2(0.975f, -0.975f),
				!m_onlySampleFaceInterior ? tcu::Vec2(1.1f, 1.06f) : tcu::Vec2(1.0f, 1.0f));

	// Read result.
	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());

	// Compare and log.
	{
		const int	bestScoreDiff	= 16;
		const int	worstScoreDiff	= 10000;

		int score = measureAccuracy(log, referenceFrame, renderedFrame, bestScoreDiff, worstScoreDiff);
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, de::toString(score).c_str());
	}

	return STOP;
}

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

TextureFilteringTests::~TextureFilteringTests (void)
{
}

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

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

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

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

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

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

	static const struct
	{
		const char*		name;
		deUint32		format;
	} formats[] =
	{
		{ "rgba8",		GL_RGBA8 }
	};

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

	// 2D cases.
	FOR_EACH(minFilter,		minFilterModes,
	FOR_EACH(magFilter,		magFilterModes,
	FOR_EACH(wrapMode,		wrapModes,
	FOR_EACH(format,		formats,
	FOR_EACH(size,			sizes2D,
		{
			string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name + "_" + formats[format].name + string("_") + sizes2D[size].name;

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

	// Cubemap cases.
	FOR_EACH(minFilter,		minFilterModes,
	FOR_EACH(magFilter,		magFilterModes,
	FOR_EACH(wrapMode,		wrapModes,
	FOR_EACH(format,		formats,
	FOR_EACH(size,			sizesCube,
		{
			string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name + "_" + formats[format].name + string("_") + sizesCube[size].name;

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

} // Accuracy
} // gles3
} // deqp
