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

#include "es3fVertexTextureTests.hpp"
#include "glsTextureTestUtil.hpp"
#include "gluTexture.hpp"
#include "gluPixelTransfer.hpp"
#include "gluTextureUtil.hpp"
#include "tcuVector.hpp"
#include "tcuMatrix.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuImageCompare.hpp"
#include "deMath.h"
#include "deRandom.hpp"
#include "deString.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;
using glu::TextureTestUtil::TEXTURETYPE_2D_ARRAY;
using glu::TextureTestUtil::TEXTURETYPE_3D;

namespace gles3
{
namespace Functional
{

static const int WIDTH_2D_ARRAY				= 128;
static const int HEIGHT_2D_ARRAY			= 128;
static const int LAYERS_2D_ARRAY			= 8;

static const int WIDTH_3D					= 64;
static const int HEIGHT_3D					= 64;
static const int DEPTH_3D					= 64;

// 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 MAX_2D_ARRAY_RENDER_WIDTH	= 128*2;
static const int MAX_2D_ARRAY_RENDER_HEIGHT	= 128*2;

static const int MAX_3D_RENDER_WIDTH		= 128*2;
static const int MAX_3D_RENDER_HEIGHT		= 128*2;

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

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

static inline Vec3 safe2DArrayTexCoords (const Vec3& raw, const IVec3& textureSize)
{
	return safeCoords(raw, textureSize, Vec3(0.5f, 0.5f, 0.0f));
}

static inline Vec3 safe3DTexCoords (const Vec3& raw, const IVec3& textureSize)
{
	return safeCoords(raw, textureSize, Vec3(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 <> struct TexTypeTcuClass<TEXTURETYPE_2D_ARRAY>	{ typedef tcu::Texture2DArray	t; };
template <> struct TexTypeTcuClass<TEXTURETYPE_3D>			{ typedef tcu::Texture3D		t; };

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

template <TextureType> struct TexTypeCoordDims;
template <> struct TexTypeCoordDims<TEXTURETYPE_2D>			{ enum { V = 2 }; };
template <> struct TexTypeCoordDims<TEXTURETYPE_CUBE>		{ enum { V = 3 }; };
template <> struct TexTypeCoordDims<TEXTURETYPE_2D_ARRAY>	{ enum { V = 3 }; };
template <> struct TexTypeCoordDims<TEXTURETYPE_3D>			{ 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_) {}
};

template <> struct
TexTypeCoordParams<TEXTURETYPE_2D_ARRAY>
{
	Mat3 transform;

	TexTypeCoordParams (const Mat3& transform_) : transform(transform_) {}
};

template <> struct
TexTypeCoordParams<TEXTURETYPE_3D>
{
	Mat3 transform;

	TexTypeCoordParams (const Mat3& transform_) : transform(transform_) {}
};

/*--------------------------------------------------------------------*//*!
 * \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);
	}
}

template <>
void PosTexCoordQuadGrid<TEXTURETYPE_2D_ARRAY>::initializeTexCoords (const IVec3& 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++)
	{
		const Vec3 rawCoord = texCoordParams.transform * Vec3((float)x / gridSizeFloat, (float)y / gridSizeFloat, 1.0f);

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

template <>
void PosTexCoordQuadGrid<TEXTURETYPE_3D>::initializeTexCoords (const IVec3& 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++)
	{
		Vec3 rawCoord = texCoordParams.transform * Vec3((float)x / gridSizeFloat, (float)y / gridSizeFloat, 1.0f);

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

} // 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());
}

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

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

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); }
static inline Vec4 sample (const tcu::Texture2DArray&	tex, const Vec3& coord, float lod, const tcu::Sampler& sam) { return tex.sample(sam, coord.x(), coord.y(), coord.z(), lod); }
static inline Vec4 sample (const tcu::Texture3D&		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 =
		"#version 300 es\n"
		"in highp vec2 a_position;\n"
		"in highp vec2 a_texCoord;\n"
		"uniform highp sampler2D u_texture;\n"
		"uniform highp float u_lod;\n"
		"out mediump vec4 v_color;\n"
		"\n"
		"void main()\n"
		"{\n"
		"	gl_Position = vec4(a_position, 0.0, 1.0);\n"
		"	v_color = textureLod(u_texture, a_texCoord, u_lod);\n"
		"}\n";

	const char* const fragmentShader =
		"#version 300 es\n"
		"layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
		"in mediump vec4 v_color;\n"
		"\n"
		"void main()\n"
		"{\n"
		"	dEQP_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.
};

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_textures[0] = DE_NULL;
	m_textures[1] = DE_NULL;
}

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

void VertexCubeTextureCase::init (void)
{
	const char* const vertexShader =
		"#version 300 es\n"
		"in highp vec2 a_position;\n"
		"in highp vec3 a_texCoord;\n"
		"uniform highp samplerCube u_texture;\n"
		"uniform highp float u_lod;\n"
		"out mediump vec4 v_color;\n"
		"\n"
		"void main()\n"
		"{\n"
		"	gl_Position = vec4(a_position, 0.0, 1.0);\n"
		"	v_color = textureLod(u_texture, a_texCoord, u_lod);\n"
		"}\n";

	const char* const fragmentShader =
		"#version 300 es\n"
		"layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
		"in mediump vec4 v_color;\n"
		"\n"
		"void main()\n"
		"{\n"
		"	dEQP_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_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 = true;
	computeReference(m_textures[textureNdx]->getRefTexture(), lod, sampler, grid, dst, dstRegion);
}

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

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

private:
	typedef PosTexCoordQuadGrid<TEXTURETYPE_2D_ARRAY> Grid;

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

	float						calculateLod				(const Mat3& transf, 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::Texture2DArray*		m_textures[2];	// 2 textures, a gradient texture and a grid texture.
};

Vertex2DArrayTextureCase::Vertex2DArrayTextureCase (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;
}

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

void Vertex2DArrayTextureCase::init (void)
{
	const char* const vertexShaderSource =
		"#version 300 es\n"
		"in highp vec2 a_position;\n"
		"in highp vec3 a_texCoord;\n"
		"uniform highp sampler2DArray u_texture;\n"
		"uniform highp float u_lod;\n"
		"out mediump vec4 v_color;\n"
		"\n"
		"void main()\n"
		"{\n"
		"	gl_Position = vec4(a_position, 0.0, 1.0);\n"
		"	v_color = textureLod(u_texture, a_texCoord, u_lod);\n"
		"}\n";

	const char* const fragmentShaderSource =
		"#version 300 es\n"
		"layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
		"in mediump vec4 v_color;\n"
		"\n"
		"void main()\n"
		"{\n"
		"	dEQP_FragColor = v_color;\n"
		"}\n";

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

	// Create shader.

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

	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
	{
		const int texWidth	= WIDTH_2D_ARRAY;
		const int texHeight	= HEIGHT_2D_ARRAY;
		const int texLayers	= LAYERS_2D_ARRAY;

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

		const int						numLevels	= deLog2Floor32(de::max(texWidth, texHeight)) + 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.
		Vertex2DArrayTextureCase::deinit();
		throw;
	}
}

void Vertex2DArrayTextureCase::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 Vertex2DArrayTextureCase::calculateLod (const Mat3& transf, const Vec2& dstSize, int textureNdx) const
{
	const tcu::Texture2DArray&	refTexture	= m_textures[textureNdx]->getRefTexture();
	const int					texWidth	= refTexture.getWidth();
	const int					texHeight	= refTexture.getHeight();

	// Calculate transformed coordinates of three screen corners.
	const Vec2					trans00		= (transf * Vec3(0.0f, 0.0f, 1.0f)).xy();
	const Vec2					trans01		= (transf * Vec3(0.0f, 1.0f, 1.0f)).xy();
	const Vec2					trans10		= (transf * Vec3(1.0f, 0.0f, 1.0f)).xy();

	// Derivates.
	const float dudx = (trans10.x() - trans00.x()) * (float)texWidth / dstSize.x();
	const float dudy = (trans01.x() - trans00.x()) * (float)texWidth / dstSize.y();
	const float dvdx = (trans10.y() - trans00.y()) * (float)texHeight / dstSize.x();
	const float dvdy = (trans01.y() - trans00.y()) * (float)texHeight / dstSize.y();

	return deFloatLog2(deFloatSqrt(de::max(dudx*dudx + dvdx*dvdx, dudy*dudy + dvdy*dvdy)));
}

Vertex2DArrayTextureCase::IterateResult Vertex2DArrayTextureCase::iterate (void)
{
	const int	viewportWidth		= deMin32(m_context.getRenderTarget().getWidth(), MAX_2D_ARRAY_RENDER_WIDTH);
	const int	viewportHeight		= deMin32(m_context.getRenderTarget().getHeight(), MAX_2D_ARRAY_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);

	// Shear by layer count to get all layers visible.
	static const float layerShearTransfData[] =
	{
		1.0f,					0.0f, 0.0f,
		0.0f,					1.0f, 0.0f,
		(float)LAYERS_2D_ARRAY, 0.0f, 0.0f
	};

	// Minification and magnification transformations.
	static const float texMinTransfData[] =
	{
		2.1f,  0.0f, -0.3f,
		0.0f,  2.1f, -0.3f,
		0.0f,  0.0f,  1.0f
	};
	static const float texMagTransfData[] =
	{
		0.4f,  0.0f,  0.8f,
		0.0f,  0.4f,  0.8f,
		0.0f,  0.0f,  1.0f
	};

	// Transformation matrices for minification and magnification.
	const Mat3 texMinTransf = Mat3(layerShearTransfData) * Mat3(texMinTransfData);
	const Mat3 texMagTransf = Mat3(layerShearTransfData) * Mat3(texMagTransfData);

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

	{
		const struct Render
		{
			const Rect	region;
			int			textureNdx;
			const Mat3	texTransform;
			Render (const Rect& r, int tN, const Mat3& tT) : region(r), textureNdx(tN), texTransform(tT) {}
		} renders[] =
		{
			Render(Rect(0,				0,				leftWidth,	bottomHeight),	0, texMinTransf),
			Render(Rect(leftWidth,		0,				rightWidth,	bottomHeight),	0, texMagTransf),
			Render(Rect(0,				bottomHeight,	leftWidth,	topHeight),		1, texMinTransf),
			Render(Rect(leftWidth,		bottomHeight,	rightWidth,	topHeight),		1, texMagTransf)
		};

		for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renders); renderNdx++)
		{
			const Render&	rend				= renders[renderNdx];
			const float		lod					= calculateLod(rend.texTransform, rend.region.size().asFloat(), rend.textureNdx);
			const bool		useSafeTexCoords	= isLevelNearest(lod > 0.0f ? m_minFilter : m_magFilter);
			const Grid		grid				(GRID_SIZE_2D_ARRAY, rend.region.size(), getTextureSize(*m_textures[rend.textureNdx]),
												 TexTypeCoordParams<TEXTURETYPE_2D_ARRAY>(rend.texTransform), 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 Vertex2DArrayTextureCase::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_2D_ARRAY, m_textures[textureNdx]->getGLTexture());
	glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S,		m_wrapS);
	glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T,		m_wrapT);
	glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER,	m_minFilter);
	glTexParameteri(GL_TEXTURE_2D_ARRAY, 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 Vertex2DArrayTextureCase::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 sub-image with given parameters.
void Vertex2DArrayTextureCase::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 Vertex3DTextureCase : public TestCase
{
public:
								Vertex3DTextureCase		(Context& testCtx, const char* name, const char* desc, deUint32 minFilter, deUint32 magFilter, deUint32 wrapS, deUint32 wrapT, deUint32 wrapR);
								~Vertex3DTextureCase	(void);

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

private:
	typedef PosTexCoordQuadGrid<TEXTURETYPE_3D> Grid;

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

	float						calculateLod			(const Mat3& transf, 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 deUint32				m_wrapR;

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

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

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

void Vertex3DTextureCase::init (void)
{
	const char* const vertexShaderSource =
		"#version 300 es\n"
		"in highp vec2 a_position;\n"
		"in highp vec3 a_texCoord;\n"
		"uniform highp sampler3D u_texture;\n"
		"uniform highp float u_lod;\n"
		"out mediump vec4 v_color;\n"
		"\n"
		"void main()\n"
		"{\n"
		"	gl_Position = vec4(a_position, 0.0, 1.0);\n"
		"	v_color = textureLod(u_texture, a_texCoord, u_lod);\n"
		"}\n";

	const char* const fragmentShaderSource =
		"#version 300 es\n"
		"layout(location = 0) out mediump vec4 dEQP_FragColor;\n"
		"in mediump vec4 v_color;\n"
		"\n"
		"void main()\n"
		"{\n"
		"	dEQP_FragColor = v_color;\n"
		"}\n";

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

	// Create shader.

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

	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
	{
		const int texWidth	= WIDTH_3D;
		const int texHeight	= HEIGHT_3D;
		const int texDepth	= DEPTH_3D;

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

		const int						numLevels	= deLog2Floor32(de::max(de::max(texWidth, texHeight), texDepth)) + 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.
		Vertex3DTextureCase::deinit();
		throw;
	}
}

void Vertex3DTextureCase::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 Vertex3DTextureCase::calculateLod (const Mat3& transf, const Vec2& dstSize, int textureNdx) const
{
	const tcu::Texture3D&	refTexture	= m_textures[textureNdx]->getRefTexture();
	const int				srcWidth	= refTexture.getWidth();
	const int				srcHeight	= refTexture.getHeight();
	const int				srcDepth	= refTexture.getDepth();

	// Calculate transformed coordinates of three screen corners.
	const Vec3				trans00		= transf * Vec3(0.0f, 0.0f, 1.0f);
	const Vec3				trans01		= transf * Vec3(0.0f, 1.0f, 1.0f);
	const Vec3				trans10		= transf * Vec3(1.0f, 0.0f, 1.0f);

	// Derivates.
	const float dudx = (trans10.x() - trans00.x()) * (float)srcWidth / dstSize.x();
	const float dudy = (trans01.x() - trans00.x()) * (float)srcWidth / dstSize.y();
	const float dvdx = (trans10.y() - trans00.y()) * (float)srcHeight / dstSize.x();
	const float dvdy = (trans01.y() - trans00.y()) * (float)srcHeight / dstSize.y();
	const float dwdx = (trans10.z() - trans00.z()) * (float)srcDepth / dstSize.x();
	const float dwdy = (trans01.z() - trans00.z()) * (float)srcDepth / dstSize.y();

	return deFloatLog2(deFloatSqrt(de::max(dudx*dudx + dvdx*dvdx + dwdx*dwdx, dudy*dudy + dvdy*dvdy + dwdy*dwdy)));
}

Vertex3DTextureCase::IterateResult Vertex3DTextureCase::iterate (void)
{
	const int	viewportWidth		= deMin32(m_context.getRenderTarget().getWidth(), MAX_3D_RENDER_WIDTH);
	const int	viewportHeight		= deMin32(m_context.getRenderTarget().getHeight(), MAX_3D_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);

	// Shear to get all slices visible.
	static const float depthShearTransfData[] =
	{
		1.0f, 0.0f, 0.0f,
		0.0f, 1.0f, 0.0f,
		1.0f, 1.0f, 0.0f
	};

	// Minification and magnification transformations.
	static const float texMinTransfData[] =
	{
		2.2f,  0.0f, -0.3f,
		0.0f,  2.2f, -0.3f,
		0.0f,  0.0f,  1.0f
	};
	static const float texMagTransfData[] =
	{
		0.4f,  0.0f,  0.8f,
		0.0f,  0.4f,  0.8f,
		0.0f,  0.0f,  1.0f
	};

	// Transformation matrices for minification and magnification.
	const Mat3 texMinTransf = Mat3(depthShearTransfData) * Mat3(texMinTransfData);
	const Mat3 texMagTransf = Mat3(depthShearTransfData) * Mat3(texMagTransfData);

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

	{
		const struct Render
		{
			const Rect	region;
			int			textureNdx;
			const Mat3		texTransform;
			Render (const Rect& r, int tN, const Mat3& tT) : region(r), textureNdx(tN), texTransform(tT) {}
		} renders[] =
		{
			Render(Rect(0,				0,				leftWidth,	bottomHeight),	0, texMinTransf),
			Render(Rect(leftWidth,		0,				rightWidth,	bottomHeight),	0, texMagTransf),
			Render(Rect(0,				bottomHeight,	leftWidth,	topHeight),		1, texMinTransf),
			Render(Rect(leftWidth,		bottomHeight,	rightWidth,	topHeight),		1, texMagTransf)
		};

		for (int renderNdx = 0; renderNdx < DE_LENGTH_OF_ARRAY(renders); renderNdx++)
		{
			const Render&	rend				= renders[renderNdx];
			const float		lod					= calculateLod(rend.texTransform, rend.region.size().asFloat(), rend.textureNdx);
			const bool		useSafeTexCoords	= isLevelNearest(lod > 0.0f ? m_minFilter : m_magFilter);
			const Grid		grid				(GRID_SIZE_3D, rend.region.size(), getTextureSize(*m_textures[rend.textureNdx]),
												 TexTypeCoordParams<TEXTURETYPE_3D>(rend.texTransform), 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 Vertex3DTextureCase::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_3D, m_textures[textureNdx]->getGLTexture());
	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S,		m_wrapS);
	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T,		m_wrapT);
	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R,		m_wrapR);
	glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
	glTexParameteri(GL_TEXTURE_3D, 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 Vertex3DTextureCase::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 sub-image with given parameters.
void Vertex3DTextureCase::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_wrapR, m_minFilter, m_magFilter), 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 group2DArray			= new TestCaseGroup(m_context, "2d_array",		"2D Array Vertex Texture Tests");
	TestCaseGroup* const group3D				= new TestCaseGroup(m_context, "3d",			"3D 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");
	TestCaseGroup* const filteringGroup2DArray	= new TestCaseGroup(m_context, "filtering",		"2D Array Vertex Texture Filtering Tests");
	TestCaseGroup* const wrapGroup2DArray		= new TestCaseGroup(m_context, "wrap",			"2D Array Vertex Texture Wrap Tests");
	TestCaseGroup* const filteringGroup3D		= new TestCaseGroup(m_context, "filtering",		"3D Vertex Texture Filtering Tests");
	TestCaseGroup* const wrapGroup3D			= new TestCaseGroup(m_context, "wrap",			"3D Vertex Texture Wrap Tests");

	group2D->addChild(filteringGroup2D);
	group2D->addChild(wrapGroup2D);
	groupCube->addChild(filteringGroupCube);
	groupCube->addChild(wrapGroupCube);
	group2DArray->addChild(filteringGroup2DArray);
	group2DArray->addChild(wrapGroup2DArray);
	group3D->addChild(filteringGroup3D);
	group3D->addChild(wrapGroup3D);

	addChild(group2D);
	addChild(groupCube);
	addChild(group2DArray);
	addChild(group3D);

	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));
		}));

	// 2D array 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;

			filteringGroup2DArray->addChild(new Vertex2DArrayTextureCase(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;

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

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

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

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

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

} // Functional
} // gles3
} // deqp
