/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 2.0 Module
 * -------------------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Vertex texture tests.
 *//*--------------------------------------------------------------------*/

#include "es2fVertexTextureTests.hpp"
#include "glsTextureTestUtil.hpp"
#include "gluTexture.hpp"
#include "gluPixelTransfer.hpp"
#include "gluTextureUtil.hpp"
#include "tcuVector.hpp"
#include "tcuMatrix.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuTexVerifierUtil.hpp"
#include "tcuImageCompare.hpp"
#include "deRandom.hpp"
#include "deString.h"
#include "deMath.h"

#include <string>
#include <vector>

#include <limits>

#include "glw.h"

using tcu::TestLog;
using tcu::Vec2;
using tcu::Vec3;
using tcu::Vec4;
using tcu::IVec2;
using tcu::IVec3;
using tcu::IVec4;
using tcu::Mat3;
using std::string;
using std::vector;

namespace deqp
{

using namespace gls::TextureTestUtil;
using namespace glu::TextureTestUtil;

using glu::TextureTestUtil::TEXTURETYPE_2D;
using glu::TextureTestUtil::TEXTURETYPE_CUBE;

namespace gles2
{
namespace Functional
{

// The 2D case draws four images.
static const int MAX_2D_RENDER_WIDTH		= 128*2;
static const int MAX_2D_RENDER_HEIGHT		= 128*2;

// The cube map case draws four 3-by-2 image groups.
static const int MAX_CUBE_RENDER_WIDTH		= 28*2*3;
static const int MAX_CUBE_RENDER_HEIGHT		= 28*2*2;

static const int GRID_SIZE_2D				= 127;
static const int GRID_SIZE_CUBE				= 63;

// Helpers for making texture coordinates "safe", i.e. move them further from coordinate bounary.

// Moves x towards the closest K+targetFraction, where K is an integer.
// E.g. moveTowardsFraction(x, 0.5f) moves x away from integer boundaries.
static inline float moveTowardsFraction (float x, float targetFraction)
{
	const float strictness = 0.5f;
	DE_ASSERT(0.0f < strictness && strictness <= 1.0f);
	DE_ASSERT(de::inBounds(targetFraction, 0.0f, 1.0f));
	const float y = x + 0.5f - targetFraction;
	return deFloatFloor(y) + deFloatFrac(y)*(1.0f-strictness) + strictness*0.5f - 0.5f + targetFraction;
}

static inline float safeCoord (float raw, int scale, float fraction)
{
	const float scaleFloat = (float)scale;
	return moveTowardsFraction(raw*scaleFloat, fraction) / scaleFloat;
}

template <int Size>
static inline tcu::Vector<float, Size> safeCoords (const tcu::Vector<float, Size>& raw, const tcu::Vector<int, Size>& scale, const tcu::Vector<float, Size>& fraction)
{
	tcu::Vector<float, Size> result;
	for (int i = 0; i < Size; i++)
		result[i] = safeCoord(raw[i], scale[i], fraction[i]);
	return result;
}

static inline Vec2 safe2DTexCoords (const Vec2& raw, const IVec2& textureSize)
{
	return safeCoords(raw, textureSize, Vec2(0.5f));
}

namespace
{

struct Rect
{
			Rect	(int x_, int y_, int w_, int h_) : x(x_), y(y_), w(w_), h(h_) {}
	IVec2	pos		(void) const { return IVec2(x, y); }
	IVec2	size	(void) const { return IVec2(w, h); }

	int		x;
	int		y;
	int		w;
	int		h;
};

template <TextureType> struct TexTypeTcuClass;
template <> struct TexTypeTcuClass<TEXTURETYPE_2D>			{ typedef tcu::Texture2D		t; };
template <> struct TexTypeTcuClass<TEXTURETYPE_CUBE>		{ typedef tcu::TextureCube		t; };

template <TextureType> struct TexTypeSizeDims;
template <> struct TexTypeSizeDims<TEXTURETYPE_2D>			{ enum { V = 2 }; };
template <> struct TexTypeSizeDims<TEXTURETYPE_CUBE>		{ enum { V = 2 }; };

template <TextureType> struct TexTypeCoordDims;
template <> struct TexTypeCoordDims<TEXTURETYPE_2D>			{ enum { V = 2 }; };
template <> struct TexTypeCoordDims<TEXTURETYPE_CUBE>		{ enum { V = 3 }; };

template <TextureType TexType> struct TexTypeSizeIVec		{ typedef tcu::Vector<int,		TexTypeSizeDims<TexType>::V>	t; };
template <TextureType TexType> struct TexTypeCoordVec		{ typedef tcu::Vector<float,	TexTypeCoordDims<TexType>::V>	t; };

template <TextureType> struct TexTypeCoordParams;

template <> struct
TexTypeCoordParams<TEXTURETYPE_2D>
{
	Vec2 scale;
	Vec2 bias;

	TexTypeCoordParams (const Vec2& scale_, const Vec2& bias_) : scale(scale_), bias(bias_) {}
};

template <> struct
TexTypeCoordParams<TEXTURETYPE_CUBE>
{
	Vec2			scale;
	Vec2			bias;
	tcu::CubeFace	face;

	TexTypeCoordParams (const Vec2& scale_, const Vec2& bias_, tcu::CubeFace face_) : scale(scale_), bias(bias_), face(face_) {}
};

/*--------------------------------------------------------------------*//*!
 * \brief Quad grid class containing position and texture coordinate data.
 *
 * A quad grid of size S means a grid consisting of S*S quads (S rows and
 * S columns). The quads are rectangles with main axis aligned sides, and
 * each consists of two triangles. Note that although there are only
 * (S+1)*(S+1) distinct vertex positions, there are S*S*4 distinct vertices
 * because we want texture coordinates to be constant across the vertices
 * of a quad (to avoid interpolation issues), and thus each quad needs its
 * own 4 vertices.
 *
 * Pointers returned by get*Ptr() are suitable for gl calls such as
 * glVertexAttribPointer() (for position and tex coord) or glDrawElements()
 * (for indices).
 *//*--------------------------------------------------------------------*/
template <TextureType TexType>
class PosTexCoordQuadGrid
{
private:
	enum { TEX_COORD_DIMS = TexTypeCoordDims <TexType>::V };
	typedef typename TexTypeCoordVec<TexType>::t	TexCoordVec;
	typedef typename TexTypeSizeIVec<TexType>::t	TexSizeIVec;
	typedef TexTypeCoordParams<TexType>				TexCoordParams;

public:
							PosTexCoordQuadGrid		(int gridSize, const IVec2& renderSize, const TexSizeIVec& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords);

	int						getSize					(void) const { return m_gridSize; }
	Vec4					getQuadLDRU				(int col, int row) const; //!< Vec4(leftX, downY, rightX, upY)
	const TexCoordVec&		getQuadTexCoord			(int col, int row) const;

	int						getNumIndices			(void) const { return m_gridSize*m_gridSize*3*2; }
	const float*			getPositionPtr			(void) const { DE_STATIC_ASSERT(sizeof(Vec2) == 2*sizeof(float)); return (float*)&m_positions[0]; }
	const float*			getTexCoordPtr			(void) const { DE_STATIC_ASSERT(sizeof(TexCoordVec) == TEX_COORD_DIMS*(int)sizeof(float)); return (float*)&m_texCoords[0]; }
	const deUint16*			getIndexPtr				(void) const { return &m_indices[0]; }

private:
	void					initializeTexCoords		(const TexSizeIVec& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords);

	const int				m_gridSize;
	vector<Vec2>			m_positions;
	vector<TexCoordVec>		m_texCoords;
	vector<deUint16>		m_indices;
};

template <TextureType TexType>
Vec4 PosTexCoordQuadGrid<TexType>::getQuadLDRU (int col, int row) const
{
	int ndx00 = (row*m_gridSize + col) * 4;
	int ndx11 = ndx00 + 3;

	return Vec4(m_positions[ndx00].x(),
				m_positions[ndx00].y(),
				m_positions[ndx11].x(),
				m_positions[ndx11].y());
}

template <TextureType TexType>
const typename TexTypeCoordVec<TexType>::t& PosTexCoordQuadGrid<TexType>::getQuadTexCoord (int col, int row) const
{
	return m_texCoords[(row*m_gridSize + col) * 4];
}

template <TextureType TexType>
PosTexCoordQuadGrid<TexType>::PosTexCoordQuadGrid (int gridSize, const IVec2& renderSize, const TexSizeIVec& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords)
	: m_gridSize(gridSize)
{
	DE_ASSERT(m_gridSize > 0 && m_gridSize*m_gridSize <= (int)std::numeric_limits<deUint16>::max() + 1);

	const float gridSizeFloat = (float)m_gridSize;

	m_positions.reserve(m_gridSize*m_gridSize*4);
	m_indices.reserve(m_gridSize*m_gridSize*3*2);

	for (int y = 0; y < m_gridSize; y++)
	for (int x = 0; x < m_gridSize; x++)
	{
		float fx0 = (float)(x+0) / gridSizeFloat;
		float fx1 = (float)(x+1) / gridSizeFloat;
		float fy0 = (float)(y+0) / gridSizeFloat;
		float fy1 = (float)(y+1) / gridSizeFloat;

		Vec2 quadVertices[4] = { Vec2(fx0, fy0), Vec2(fx1, fy0), Vec2(fx0, fy1), Vec2(fx1, fy1) };

		int firstNdx = (int)m_positions.size();

		for (int i = 0; i < DE_LENGTH_OF_ARRAY(quadVertices); i++)
			m_positions.push_back(safeCoords(quadVertices[i], renderSize, Vec2(0.0f)) * 2.0f - 1.0f);

		m_indices.push_back(deUint16(firstNdx + 0));
		m_indices.push_back(deUint16(firstNdx + 1));
		m_indices.push_back(deUint16(firstNdx + 2));

		m_indices.push_back(deUint16(firstNdx + 1));
		m_indices.push_back(deUint16(firstNdx + 3));
		m_indices.push_back(deUint16(firstNdx + 2));
	}

	m_texCoords.reserve(m_gridSize*m_gridSize*4);
	initializeTexCoords(textureSize, texCoordParams, useSafeTexCoords);

	DE_ASSERT((int)m_positions.size() == m_gridSize*m_gridSize*4);
	DE_ASSERT((int)m_indices.size() == m_gridSize*m_gridSize*3*2);
	DE_ASSERT((int)m_texCoords.size() == m_gridSize*m_gridSize*4);
}

template <>
void PosTexCoordQuadGrid<TEXTURETYPE_2D>::initializeTexCoords (const IVec2& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords)
{
	DE_ASSERT(m_texCoords.empty());

	const float gridSizeFloat = (float)m_gridSize;

	for (int y = 0; y < m_gridSize; y++)
	for (int x = 0; x < m_gridSize; x++)
	{
		Vec2 rawCoord = Vec2((float)x / gridSizeFloat, (float)y / gridSizeFloat) * texCoordParams.scale + texCoordParams.bias;

		for (int i = 0; i < 4; i++)
			m_texCoords.push_back(useSafeTexCoords ? safe2DTexCoords(rawCoord, textureSize) : rawCoord);
	}
}

template <>
void PosTexCoordQuadGrid<TEXTURETYPE_CUBE>::initializeTexCoords (const IVec2& textureSize, const TexCoordParams& texCoordParams, bool useSafeTexCoords)
{
	DE_ASSERT(m_texCoords.empty());

	const float		gridSizeFloat	= (float)m_gridSize;
	vector<float>	texBoundaries;
	computeQuadTexCoordCube(texBoundaries, texCoordParams.face);
	const Vec3		coordA			= Vec3(texBoundaries[0], texBoundaries[1], texBoundaries[2]);
	const Vec3		coordB			= Vec3(texBoundaries[3], texBoundaries[4], texBoundaries[5]);
	const Vec3		coordC			= Vec3(texBoundaries[6], texBoundaries[7], texBoundaries[8]);
	const Vec3		coordAB			= coordB - coordA;
	const Vec3		coordAC			= coordC - coordA;

	for (int y = 0; y < m_gridSize; y++)
	for (int x = 0; x < m_gridSize; x++)
	{
		const Vec2 rawFaceCoord		= texCoordParams.scale * Vec2((float)x / gridSizeFloat, (float)y / gridSizeFloat) + texCoordParams.bias;
		const Vec2 safeFaceCoord	= useSafeTexCoords ? safe2DTexCoords(rawFaceCoord, textureSize) : rawFaceCoord;
		const Vec3 texCoord			= coordA + coordAC*safeFaceCoord.x() + coordAB*safeFaceCoord.y();

		for (int i = 0; i < 4; i++)
			m_texCoords.push_back(texCoord);
	}
}

} // anonymous

static inline bool isLevelNearest (deUint32 filter)
{
	return filter == GL_NEAREST || filter == GL_NEAREST_MIPMAP_NEAREST || filter == GL_NEAREST_MIPMAP_LINEAR;
}

static inline IVec2 getTextureSize (const glu::Texture2D& tex)
{
	const tcu::Texture2D& ref = tex.getRefTexture();
	return IVec2(ref.getWidth(), ref.getHeight());
}

static inline IVec2 getTextureSize (const glu::TextureCube& tex)
{
	const tcu::TextureCube& ref = tex.getRefTexture();
	return IVec2(ref.getSize(), ref.getSize());
}

template <TextureType TexType>
static void setPixelColors (const vector<Vec4>& quadColors, const Rect& region, const PosTexCoordQuadGrid<TexType>& grid, tcu::Surface& dst)
{
	const int gridSize = grid.getSize();

	for (int y = 0; y < gridSize; y++)
	for (int x = 0; x < gridSize; x++)
	{
		const Vec4	color	= quadColors[y*gridSize + x];
		const Vec4	ldru	= grid.getQuadLDRU(x, y) * 0.5f + 0.5f; // [-1, 1] -> [0, 1]
		const int	ix0		= deCeilFloatToInt32(ldru.x() * (float)region.w - 0.5f);
		const int	ix1		= deCeilFloatToInt32(ldru.z() * (float)region.w - 0.5f);
		const int	iy0		= deCeilFloatToInt32(ldru.y() * (float)region.h - 0.5f);
		const int	iy1		= deCeilFloatToInt32(ldru.w() * (float)region.h - 0.5f);

		for (int iy = iy0; iy < iy1; iy++)
		for (int ix = ix0; ix < ix1; ix++)
		{
			DE_ASSERT(deInBounds32(ix + region.x, 0, dst.getWidth()));
			DE_ASSERT(deInBounds32(iy + region.y, 0, dst.getHeight()));

			dst.setPixel(ix + region.x, iy + region.y, tcu::RGBA(color));
		}
	}
}

static inline Vec4 sample (const tcu::Texture2D&		tex, const Vec2& coord, float lod, const tcu::Sampler& sam) { return tex.sample(sam, coord.x(), coord.y(), lod); }
static inline Vec4 sample (const tcu::TextureCube&		tex, const Vec3& coord, float lod, const tcu::Sampler& sam) { return tex.sample(sam, coord.x(), coord.y(), coord.z(), lod); }

template <TextureType TexType>
void computeReference (const typename TexTypeTcuClass<TexType>::t& texture, float lod, const tcu::Sampler& sampler, const PosTexCoordQuadGrid<TexType>& grid, tcu::Surface& dst, const Rect& dstRegion)
{
	const int		gridSize	= grid.getSize();
	vector<Vec4>	quadColors	(gridSize*gridSize);

	for (int y = 0; y < gridSize; y++)
	for (int x = 0; x < gridSize; x++)
	{
		const int										ndx		= y*gridSize + x;
		const typename TexTypeCoordVec<TexType>::t&		coord	= grid.getQuadTexCoord(x, y);

		quadColors[ndx] = sample(texture, coord, lod, sampler);
	}

	setPixelColors(quadColors, dstRegion, grid, dst);
}

static bool compareImages (const glu::RenderContext& renderCtx, tcu::TestLog& log, const tcu::Surface& ref, const tcu::Surface& res)
{
	DE_ASSERT(renderCtx.getRenderTarget().getNumSamples() == 0);

	const tcu::RGBA threshold = renderCtx.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(15,15,15,15);
	return tcu::pixelThresholdCompare(log, "Result", "Image compare result", ref, res, threshold, tcu::COMPARE_LOG_RESULT);
}

class Vertex2DTextureCase : public TestCase
{
public:
								Vertex2DTextureCase		(Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT);
								~Vertex2DTextureCase	(void);

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

private:
	typedef PosTexCoordQuadGrid<TEXTURETYPE_2D> Grid;

								Vertex2DTextureCase		(const Vertex2DTextureCase& other);
	Vertex2DTextureCase&		operator=				(const Vertex2DTextureCase& other);

	float						calculateLod			(const Vec2& texScale, const Vec2& dstSize, int textureNdx) const;
	void						setupShaderInputs		(int textureNdx, float lod, const Grid& grid) const;
	void						renderCell				(int textureNdx, float lod, const Grid& grid) const;
	void						computeReferenceCell	(int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const;

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

	const glu::ShaderProgram*	m_program;
	glu::Texture2D*				m_textures[2];	// 2 textures, a gradient texture and a grid texture.
};

Vertex2DTextureCase::Vertex2DTextureCase (Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT)
	: TestCase				(testCtx, tcu::NODETYPE_SELF_VALIDATE, name, desc)
	, m_minFilter			(minFilter)
	, m_magFilter			(magFilter)
	, m_wrapS				(wrapS)
	, m_wrapT				(wrapT)
	, m_program				(DE_NULL)
{
	m_textures[0] = DE_NULL;
	m_textures[1] = DE_NULL;
}

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

void Vertex2DTextureCase::init (void)
{
	const char* const vertexShader =
		"attribute highp vec2 a_position;\n"
		"attribute highp vec2 a_texCoord;\n"
		"uniform highp sampler2D u_texture;\n"
		"uniform highp float u_lod;\n"
		"varying mediump vec4 v_color;\n"
		"\n"
		"void main()\n"
		"{\n"
		"	gl_Position = vec4(a_position, 0.0, 1.0);\n"
		"	v_color = texture2DLod(u_texture, a_texCoord, u_lod);\n"
		"}\n";

	const char* const fragmentShader =
		"varying mediump vec4 v_color;\n"
		"\n"
		"void main()\n"
		"{\n"
		"	gl_FragColor = v_color;\n"
		"}\n";

	if (m_context.getRenderTarget().getNumSamples() != 0)
		throw tcu::NotSupportedError("MSAA config not supported by this test");

	DE_ASSERT(!m_program);
	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShader, fragmentShader));

	if(!m_program->isOk())
	{
		m_testCtx.getLog() << *m_program;

		GLint maxVertexTextures;
		glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextures);

		if (maxVertexTextures < 1)
			throw tcu::NotSupportedError("Vertex texture image units not supported", "", __FILE__, __LINE__);
		else
			TCU_FAIL("Failed to compile shader");
	}

	// Make the textures.
	try
	{
		// Compute suitable power-of-two sizes (for mipmaps).
		const int texWidth		= 1 << deLog2Ceil32(MAX_2D_RENDER_WIDTH / 2);
		const int texHeight		= 1 << deLog2Ceil32(MAX_2D_RENDER_HEIGHT / 2);

		for (int i = 0; i < 2; i++)
		{
			DE_ASSERT(!m_textures[i]);
			m_textures[i] = new glu::Texture2D(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, texWidth, texHeight);
		}

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

		// Fill first with gradient texture.
		for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
		{
			const Vec4 gMin = Vec4(-0.5f, -0.5f, -0.5f, 2.0f)*cScale + cBias;
			const Vec4 gMax = 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++)
		{
			const deUint32 step		= 0x00ffffff / numLevels;
			const deUint32 rgb		= step*levelNdx;
			const deUint32 colorA	= 0xff000000 | rgb;
			const 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 (int i = 0; i < 2; i++)
			m_textures[i]->upload();
	}
	catch (const std::exception&)
	{
		// Clean up to save memory.
		Vertex2DTextureCase::deinit();
		throw;
	}
}

void Vertex2DTextureCase::deinit (void)
{
	for (int i = 0; i < 2; i++)
	{
		delete m_textures[i];
		m_textures[i] = DE_NULL;
	}

	delete m_program;
	m_program = DE_NULL;
}

float Vertex2DTextureCase::calculateLod (const Vec2& texScale, const Vec2& dstSize, int textureNdx) const
{
	const tcu::Texture2D&		refTexture	= m_textures[textureNdx]->getRefTexture();
	const Vec2					srcSize		= Vec2((float)refTexture.getWidth(), (float)refTexture.getHeight());
	const Vec2					sizeRatio	= texScale*srcSize / dstSize;

	// \note In this particular case dv/dx and du/dy are zero, simplifying the expression.
	return deFloatLog2(de::max(sizeRatio.x(), sizeRatio.y()));
}

Vertex2DTextureCase::IterateResult Vertex2DTextureCase::iterate (void)
{
	const int	viewportWidth		= deMin32(m_context.getRenderTarget().getWidth(), MAX_2D_RENDER_WIDTH);
	const int	viewportHeight		= deMin32(m_context.getRenderTarget().getHeight(), MAX_2D_RENDER_HEIGHT);

	const int	viewportXOffsetMax	= m_context.getRenderTarget().getWidth() - viewportWidth;
	const int	viewportYOffsetMax	= m_context.getRenderTarget().getHeight() - viewportHeight;

	de::Random	rnd					(deStringHash(getName()));

	const int	viewportXOffset		= rnd.getInt(0, viewportXOffsetMax);
	const int	viewportYOffset		= rnd.getInt(0, viewportYOffsetMax);

	glUseProgram(m_program->getProgram());

	// Divide viewport into 4 cells.
	const int leftWidth		= viewportWidth / 2;
	const int rightWidth	= viewportWidth - leftWidth;
	const int bottomHeight	= viewportHeight / 2;
	const int topHeight		= viewportHeight - bottomHeight;

	// Clear.
	glClearColor(0.125f, 0.25f, 0.5f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT);

	// Texture scaling and offsetting vectors.
	const Vec2 texMinScale		(+1.8f, +1.8f);
	const Vec2 texMinOffset		(-0.3f, -0.2f);
	const Vec2 texMagScale		(+0.3f, +0.3f);
	const Vec2 texMagOffset		(+0.9f, +0.8f);

	// Surface for the reference image.
	tcu::Surface refImage(viewportWidth, viewportHeight);

	{
		const struct Render
		{
			const Rect	region;
			int			textureNdx;
			const Vec2	texCoordScale;
			const Vec2	texCoordOffset;
			Render (const Rect& r, int tN, const Vec2& tS, const Vec2& tO) : region(r), textureNdx(tN), texCoordScale(tS), texCoordOffset(tO) {}
		} renders[] =
		{
			Render(Rect(0,				0,				leftWidth,	bottomHeight),	0, texMinScale, texMinOffset),
			Render(Rect(leftWidth,		0,				rightWidth,	bottomHeight),	0, texMagScale, texMagOffset),
			Render(Rect(0,				bottomHeight,	leftWidth,	topHeight),		1, texMinScale, texMinOffset),
			Render(Rect(leftWidth,		bottomHeight,	rightWidth,	topHeight),		1, texMagScale, texMagOffset)
		};

		for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renders); renderNdx++)
		{
			const Render&	rend				= renders[renderNdx];
			const float		lod					= calculateLod(rend.texCoordScale, rend.region.size().asFloat(), rend.textureNdx);
			const bool		useSafeTexCoords	= isLevelNearest(lod > 0.0f ? m_minFilter : m_magFilter);
			const Grid		grid				(GRID_SIZE_2D, rend.region.size(), getTextureSize(*m_textures[rend.textureNdx]),
												 TexTypeCoordParams<TEXTURETYPE_2D>(rend.texCoordScale, rend.texCoordOffset), useSafeTexCoords);

			glViewport(viewportXOffset + rend.region.x, viewportYOffset + rend.region.y, rend.region.w, rend.region.h);
			renderCell				(rend.textureNdx, lod, grid);
			computeReferenceCell	(rend.textureNdx, lod, grid, refImage, rend.region);
		}
	}

	// Read back rendered results.
	tcu::Surface resImage(viewportWidth, viewportHeight);
	glu::readPixels(m_context.getRenderContext(), viewportXOffset, viewportYOffset, resImage.getAccess());

	glUseProgram(0);

	// Compare and log.
	{
		const bool isOk = compareImages(m_context.getRenderContext(), m_testCtx.getLog(), refImage, resImage);

		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
								isOk ? "Pass"				: "Image comparison failed");
	}

	return STOP;
}

void Vertex2DTextureCase::setupShaderInputs (int textureNdx, float lod, const Grid& grid) const
{
	const deUint32 programID = m_program->getProgram();

	// SETUP ATTRIBUTES.

	{
		const int positionLoc = glGetAttribLocation(programID, "a_position");
		if (positionLoc != -1)
		{
			glEnableVertexAttribArray(positionLoc);
			glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, grid.getPositionPtr());
		}
	}

	{
		const int texCoordLoc = glGetAttribLocation(programID, "a_texCoord");
		if (texCoordLoc != -1)
		{
			glEnableVertexAttribArray(texCoordLoc);
			glVertexAttribPointer(texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, grid.getTexCoordPtr());
		}
	}

	// SETUP UNIFORMS.

	{
		const int lodLoc = glGetUniformLocation(programID, "u_lod");
		if (lodLoc != -1)
			glUniform1f(lodLoc, lod);
	}

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_textures[textureNdx]->getGLTexture());
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	m_magFilter);

	{
		const int texLoc = glGetUniformLocation(programID, "u_texture");
		if (texLoc != -1)
			glUniform1i(texLoc, 0);
	}
}

// Renders one sub-image with given parameters.
void Vertex2DTextureCase::renderCell (int textureNdx, float lod, const Grid& grid) const
{
	setupShaderInputs(textureNdx, lod, grid);
	glDrawElements(GL_TRIANGLES, grid.getNumIndices(), GL_UNSIGNED_SHORT, grid.getIndexPtr());
}

void Vertex2DTextureCase::computeReferenceCell (int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const
{
	computeReference(m_textures[textureNdx]->getRefTexture(), lod, glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter), grid, dst, dstRegion);
}

class VertexCubeTextureCase : public TestCase
{
public:
								VertexCubeTextureCase	(Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT);
								~VertexCubeTextureCase	(void);

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

private:
	typedef PosTexCoordQuadGrid<TEXTURETYPE_CUBE> Grid;

								VertexCubeTextureCase	(const VertexCubeTextureCase& other);
	VertexCubeTextureCase&		operator=				(const VertexCubeTextureCase& other);

	float						calculateLod			(const Vec2& texScale, const Vec2& dstSize, int textureNdx) const;
	void						setupShaderInputs		(int textureNdx, float lod, const Grid& grid) const;
	void						renderCell				(int textureNdx, float lod, const Grid& grid) const;
	void						computeReferenceCell	(int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const;

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

	const glu::ShaderProgram*	m_program;
	glu::TextureCube*			m_textures[2];	// 2 textures, a gradient texture and a grid texture.

	bool						m_isES3Capable;
};

VertexCubeTextureCase::VertexCubeTextureCase (Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT)
	: TestCase				(testCtx, tcu::NODETYPE_SELF_VALIDATE, name, desc)
	, m_minFilter			(minFilter)
	, m_magFilter			(magFilter)
	, m_wrapS				(wrapS)
	, m_wrapT				(wrapT)
	, m_program				(DE_NULL)
	, m_isES3Capable		(false)
{
	m_textures[0] = DE_NULL;
	m_textures[1] = DE_NULL;
}

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

void VertexCubeTextureCase::init (void)
{
	const char* const vertexShader =
		"attribute highp vec2 a_position;\n"
		"attribute highp vec3 a_texCoord;\n"
		"uniform highp samplerCube u_texture;\n"
		"uniform highp float u_lod;\n"
		"varying mediump vec4 v_color;\n"
		"\n"
		"void main()\n"
		"{\n"
		"	gl_Position = vec4(a_position, 0.0, 1.0);\n"
		"	v_color = textureCubeLod(u_texture, a_texCoord, u_lod);\n"
		"}\n";

	const char* const fragmentShader =
		"varying mediump vec4 v_color;\n"
		"\n"
		"void main()\n"
		"{\n"
		"	gl_FragColor = v_color;\n"
		"}\n";

	// GL_MAJOR_VERSION query does not exist on GLES2
	// so succeeding query implies GLES3+ hardware.
	glw::GLint majorVersion = 0;
	glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
	m_isES3Capable = (glGetError() == GL_NO_ERROR);

	if (m_context.getRenderTarget().getNumSamples() != 0)
		throw tcu::NotSupportedError("MSAA config not supported by this test");

	DE_ASSERT(!m_program);
	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShader, fragmentShader));

	if(!m_program->isOk())
	{
		m_testCtx.getLog() << *m_program;

		GLint maxVertexTextures;
		glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &maxVertexTextures);

		if (maxVertexTextures < 1)
			throw tcu::NotSupportedError("Vertex texture image units not supported", "", __FILE__, __LINE__);
		else
			TCU_FAIL("Failed to compile shader");
	}

	// Make the textures.
	try
	{
		// Compute suitable power-of-two sizes (for mipmaps).
		const int texWidth		= 1 << deLog2Ceil32(MAX_CUBE_RENDER_WIDTH / 3 / 2);
		const int texHeight		= 1 << deLog2Ceil32(MAX_CUBE_RENDER_HEIGHT / 2 / 2);

		DE_ASSERT(texWidth == texHeight);
		DE_UNREF(texHeight);

		for (int i = 0; i < 2; i++)
		{
			DE_ASSERT(!m_textures[i]);
			m_textures[i] = new glu::TextureCube(m_context.getRenderContext(), GL_RGB, GL_UNSIGNED_BYTE, texWidth);
		}

		const bool						mipmaps		= deIsPowerOfTwo32(texWidth) != DE_FALSE;
		const int						numLevels	= mipmaps ? deLog2Floor32(texWidth)+1 : 1;
		const tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(m_textures[0]->getRefTexture().getFormat());
		const Vec4						cBias		= fmtInfo.valueMin;
		const Vec4						cScale		= fmtInfo.valueMax-fmtInfo.valueMin;

		// Fill first with gradient texture.
		static const Vec4 gradients[tcu::CUBEFACE_LAST][2] =
		{
			{ Vec4(-1.0f, -1.0f, -1.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative x
			{ Vec4( 0.0f, -1.0f, -1.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive x
			{ Vec4(-1.0f,  0.0f, -1.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // negative y
			{ Vec4(-1.0f, -1.0f,  0.0f, 2.0f), Vec4(1.0f, 1.0f, 1.0f, 0.0f) }, // positive y
			{ Vec4(-1.0f, -1.0f, -1.0f, 0.0f), Vec4(1.0f, 1.0f, 1.0f, 1.0f) }, // negative z
			{ Vec4( 0.0f,  0.0f,  0.0f, 2.0f), 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++)
			{
				const deUint32 step		= 0x00ffffff / (numLevels*tcu::CUBEFACE_LAST);
				const deUint32 rgb		= step*levelNdx*face;
				const deUint32 colorA	= 0xff000000 | rgb;
				const 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 (int i = 0; i < 2; i++)
			m_textures[i]->upload();
	}
	catch (const std::exception&)
	{
		// Clean up to save memory.
		VertexCubeTextureCase::deinit();
		throw;
	}
}

void VertexCubeTextureCase::deinit (void)
{
	for (int i = 0; i < 2; i++)
	{
		delete m_textures[i];
		m_textures[i] = DE_NULL;
	}

	delete m_program;
	m_program = DE_NULL;
}

float VertexCubeTextureCase::calculateLod (const Vec2& texScale, const Vec2& dstSize, int textureNdx) const
{
	const tcu::TextureCube&		refTexture	= m_textures[textureNdx]->getRefTexture();
	const Vec2					srcSize		= Vec2((float)refTexture.getSize(), (float)refTexture.getSize());
	const Vec2					sizeRatio	= texScale*srcSize / dstSize;

	// \note In this particular case, dv/dx and du/dy are zero, simplifying the expression.
	return deFloatLog2(de::max(sizeRatio.x(), sizeRatio.y()));
}

VertexCubeTextureCase::IterateResult VertexCubeTextureCase::iterate (void)
{
	const int	viewportWidth		= deMin32(m_context.getRenderTarget().getWidth(), MAX_CUBE_RENDER_WIDTH);
	const int	viewportHeight		= deMin32(m_context.getRenderTarget().getHeight(), MAX_CUBE_RENDER_HEIGHT);

	const int	viewportXOffsetMax	= m_context.getRenderTarget().getWidth() - viewportWidth;
	const int	viewportYOffsetMax	= m_context.getRenderTarget().getHeight() - viewportHeight;

	de::Random	rnd					(deStringHash(getName()));

	const int	viewportXOffset		= rnd.getInt(0, viewportXOffsetMax);
	const int	viewportYOffset		= rnd.getInt(0, viewportYOffsetMax);

	glUseProgram(m_program->getProgram());

	// Divide viewport into 4 areas.
	const int leftWidth		= viewportWidth / 2;
	const int rightWidth	= viewportWidth - leftWidth;
	const int bottomHeight	= viewportHeight / 2;
	const int topHeight		= viewportHeight - bottomHeight;

	// Clear.
	glClearColor(0.125f, 0.25f, 0.5f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT);

	// Texture scaling and offsetting vectors.
	const Vec2 texMinScale		(1.0f, 1.0f);
	const Vec2 texMinOffset		(0.0f, 0.0f);
	const Vec2 texMagScale		(0.3f, 0.3f);
	const Vec2 texMagOffset		(0.5f, 0.3f);

	// Surface for the reference image.
	tcu::Surface refImage(viewportWidth, viewportHeight);

	// Each of the four areas is divided into 6 cells.
	const int defCellWidth	= viewportWidth / 2 / 3;
	const int defCellHeight	= viewportHeight / 2 / 2;

	for (int i = 0; i < tcu::CUBEFACE_LAST; i++)
	{
		const int	cellOffsetX			= defCellWidth * (i % 3);
		const int	cellOffsetY			= defCellHeight * (i / 3);
		const bool	isRightmostCell		= i == 2 || i == 5;
		const bool	isTopCell			= i >= 3;
		const int	leftCellWidth		= isRightmostCell	? leftWidth		- cellOffsetX : defCellWidth;
		const int	rightCellWidth		= isRightmostCell	? rightWidth	- cellOffsetX : defCellWidth;
		const int	bottomCellHeight	= isTopCell			? bottomHeight	- cellOffsetY : defCellHeight;
		const int	topCellHeight		= isTopCell			? topHeight		- cellOffsetY : defCellHeight;

		const struct Render
		{
			const Rect	region;
			int			textureNdx;
			const Vec2	texCoordScale;
			const Vec2	texCoordOffset;
			Render (const Rect& r, int tN, const Vec2& tS, const Vec2& tO) : region(r), textureNdx(tN), texCoordScale(tS), texCoordOffset(tO) {}
		} renders[] =
		{
			Render(Rect(cellOffsetX + 0,			cellOffsetY + 0,				leftCellWidth,	bottomCellHeight),	0, texMinScale, texMinOffset),
			Render(Rect(cellOffsetX + leftWidth,	cellOffsetY + 0,				rightCellWidth,	bottomCellHeight),	0, texMagScale, texMagOffset),
			Render(Rect(cellOffsetX + 0,			cellOffsetY + bottomHeight,		leftCellWidth,	topCellHeight),		1, texMinScale, texMinOffset),
			Render(Rect(cellOffsetX + leftWidth,	cellOffsetY + bottomHeight,		rightCellWidth,	topCellHeight),		1, texMagScale, texMagOffset)
		};

		for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renders); renderNdx++)
		{
			const Render&	rend				= renders[renderNdx];
			const float		lod					= calculateLod(rend.texCoordScale, rend.region.size().asFloat(), rend.textureNdx);
			const bool		useSafeTexCoords	= isLevelNearest(lod > 0.0f ? m_minFilter : m_magFilter);
			const Grid		grid				(GRID_SIZE_CUBE, rend.region.size(), getTextureSize(*m_textures[rend.textureNdx]),
												 TexTypeCoordParams<TEXTURETYPE_CUBE>(rend.texCoordScale, rend.texCoordOffset, (tcu::CubeFace)i), useSafeTexCoords);

			glViewport(viewportXOffset + rend.region.x, viewportYOffset + rend.region.y, rend.region.w, rend.region.h);
			renderCell				(rend.textureNdx, lod, grid);
			computeReferenceCell	(rend.textureNdx, lod, grid, refImage, rend.region);
		}
	}

	// Read back rendered results.
	tcu::Surface resImage(viewportWidth, viewportHeight);
	glu::readPixels(m_context.getRenderContext(), viewportXOffset, viewportYOffset, resImage.getAccess());

	glUseProgram(0);

	// Compare and log.
	{
		const bool isOk = compareImages(m_context.getRenderContext(), m_testCtx.getLog(), refImage, resImage);

		m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
								isOk ? "Pass"				: "Image comparison failed");
	}

	return STOP;
}

void VertexCubeTextureCase::setupShaderInputs (int textureNdx, float lod, const Grid& grid) const
{
	const deUint32 programID = m_program->getProgram();

	// SETUP ATTRIBUTES.

	{
		const int positionLoc = glGetAttribLocation(programID, "a_position");
		if (positionLoc != -1)
		{
			glEnableVertexAttribArray(positionLoc);
			glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, grid.getPositionPtr());
		}
	}

	{
		const int texCoordLoc = glGetAttribLocation(programID, "a_texCoord");
		if (texCoordLoc != -1)
		{
			glEnableVertexAttribArray(texCoordLoc);
			glVertexAttribPointer(texCoordLoc, 3, GL_FLOAT, GL_FALSE, 0, grid.getTexCoordPtr());
		}
	}

	// SETUP UNIFORMS.

	{
		const int lodLoc = glGetUniformLocation(programID, "u_lod");
		if (lodLoc != -1)
			glUniform1f(lodLoc, lod);
	}

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_CUBE_MAP, m_textures[textureNdx]->getGLTexture());
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S,		m_wrapS);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T,		m_wrapT);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER,	m_minFilter);
	glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER,	m_magFilter);

	{
		const int texLoc = glGetUniformLocation(programID, "u_texture");
		if (texLoc != -1)
			glUniform1i(texLoc, 0);
	}
}

// Renders one cube face with given parameters.
void VertexCubeTextureCase::renderCell (int textureNdx, float lod, const Grid& grid) const
{
	setupShaderInputs(textureNdx, lod, grid);
	glDrawElements(GL_TRIANGLES, grid.getNumIndices(), GL_UNSIGNED_SHORT, grid.getIndexPtr());
}

// Computes reference for one cube face with given parameters.
void VertexCubeTextureCase::computeReferenceCell (int textureNdx, float lod, const Grid& grid, tcu::Surface& dst, const Rect& dstRegion) const
{
	tcu::Sampler sampler = glu::mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
	sampler.seamlessCubeMap = m_isES3Capable;
	computeReference(m_textures[textureNdx]->getRefTexture(), lod, sampler, grid, dst, dstRegion);
}

VertexTextureTests::VertexTextureTests (Context& context)
	: TestCaseGroup(context, "vertex", "Vertex Texture Tests")
{
}

VertexTextureTests::~VertexTextureTests(void)
{
}

void VertexTextureTests::init (void)
{
	// 2D and cube map groups, and their filtering and wrap sub-groups.
	TestCaseGroup* const group2D				= new TestCaseGroup(m_context, "2d",			"2D Vertex Texture Tests");
	TestCaseGroup* const groupCube				= new TestCaseGroup(m_context, "cube",			"Cube Map Vertex Texture Tests");
	TestCaseGroup* const filteringGroup2D		= new TestCaseGroup(m_context, "filtering",		"2D Vertex Texture Filtering Tests");
	TestCaseGroup* const wrapGroup2D			= new TestCaseGroup(m_context, "wrap",			"2D Vertex Texture Wrap Tests");
	TestCaseGroup* const filteringGroupCube		= new TestCaseGroup(m_context, "filtering",		"Cube Map Vertex Texture Filtering Tests");
	TestCaseGroup* const wrapGroupCube			= new TestCaseGroup(m_context, "wrap",			"Cube Map Vertex Texture Wrap Tests");

	group2D->addChild(filteringGroup2D);
	group2D->addChild(wrapGroup2D);
	groupCube->addChild(filteringGroupCube);
	groupCube->addChild(wrapGroupCube);

	addChild(group2D);
	addChild(groupCube);

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

	static const struct
	{
		const char*		name;
		GLenum			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;
		GLenum			mode;
	} magFilterModes[] =
	{
		{ "nearest",	GL_NEAREST	},
		{ "linear",		GL_LINEAR	}
	};

#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,
		{
			const string name = string("") + minFilterModes[minFilter].name + "_" + magFilterModes[magFilter].name + "_" + wrapModes[wrapMode].name;

			filteringGroup2D->addChild(new Vertex2DTextureCase(m_context,
															   name.c_str(), "",
															   minFilterModes[minFilter].mode,
															   magFilterModes[magFilter].mode,
															   wrapModes[wrapMode].mode,
															   wrapModes[wrapMode].mode));
		})));

	FOR_EACH(wrapSMode,		wrapModes,
	FOR_EACH(wrapTMode,		wrapModes,
		{
			const string name = string("") + wrapModes[wrapSMode].name + "_" + wrapModes[wrapTMode].name;

			wrapGroup2D->addChild(new Vertex2DTextureCase(m_context,
														  name.c_str(), "",
														  GL_LINEAR_MIPMAP_LINEAR,
														  GL_LINEAR,
														  wrapModes[wrapSMode].mode,
														  wrapModes[wrapTMode].mode));
		}));

	// Cube map cases.

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

			filteringGroupCube->addChild(new VertexCubeTextureCase(m_context,
																   name.c_str(), "",
																   minFilterModes[minFilter].mode,
																   magFilterModes[magFilter].mode,
																   wrapModes[wrapMode].mode,
																   wrapModes[wrapMode].mode));
		})));

	FOR_EACH(wrapSMode,		wrapModes,
	FOR_EACH(wrapTMode,		wrapModes,
		{
			const string name = string("") + wrapModes[wrapSMode].name + "_" + wrapModes[wrapTMode].name;

			wrapGroupCube->addChild(new VertexCubeTextureCase(m_context,
															  name.c_str(), "",
															  GL_LINEAR_MIPMAP_LINEAR,
															  GL_LINEAR,
															  wrapModes[wrapSMode].mode,
															  wrapModes[wrapTMode].mode));
		}));
}

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