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

	m_isES3Capable = glu::IsES3Compatible(m_context.getRenderContext().getFunctions());

	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
