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

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, toVec4(tcu::RGBA(colorA))*cScale + cBias, toVec4(tcu::RGBA(colorB))*cScale + cBias);
			}

			// Upload.
			for (std::vector<glu::Texture2D*>::iterator i = m_textures.begin(); i != m_textures.end(); i++)
				(*i)->upload();
		}
	}
	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(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(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(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(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, toVec4(tcu::RGBA(colorA))*cScale + cBias, toVec4(tcu::RGBA(colorB))*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 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(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,
				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,
				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,
				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,
				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
