/*-------------------------------------------------------------------------
 * 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 Texture unit usage tests.
 *
 * \todo [2012-07-12 nuutti] Come up with a good way to make these tests faster.
 *//*--------------------------------------------------------------------*/

#include "es2fTextureUnitTests.hpp"
#include "glsTextureTestUtil.hpp"
#include "gluTextureUtil.hpp"
#include "gluContextInfo.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuImageCompare.hpp"
#include "tcuMatrix.hpp"
#include "tcuRenderTarget.hpp"
#include "sglrContextUtil.hpp"
#include "sglrReferenceContext.hpp"
#include "sglrGLContext.hpp"
#include "deMath.h"
#include "deStringUtil.hpp"
#include "deRandom.hpp"

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

using tcu::Vec2;
using tcu::Vec3;
using tcu::Vec4;
using tcu::IVec2;
using tcu::Mat3;
using std::vector;
using std::string;
using namespace glw; // GL types

namespace deqp
{

using namespace gls::TextureTestUtil;

namespace gles2
{
namespace Functional
{

static const int VIEWPORT_WIDTH			= 128;
static const int VIEWPORT_HEIGHT		= 128;

static const int TEXTURE_WIDTH_2D		= 128;
static const int TEXTURE_HEIGHT_2D		= 128;

// \note Cube map texture size is larger in order to make minifications possible - otherwise would need to display different faces at same time.
static const int TEXTURE_WIDTH_CUBE		= 256;
static const int TEXTURE_HEIGHT_CUBE	= 256;

static const int GRID_CELL_SIZE			= 8;

static const GLenum s_testFormats[] =
{
	GL_RGB,
	GL_RGBA,
	GL_ALPHA,
	GL_LUMINANCE,
	GL_LUMINANCE_ALPHA
};

static const GLenum s_testDataTypes[] =
{
	GL_UNSIGNED_BYTE,
	GL_UNSIGNED_SHORT_5_6_5,
	GL_UNSIGNED_SHORT_4_4_4_4,
	GL_UNSIGNED_SHORT_5_5_5_1,
};

static const GLenum s_testWrapModes[] =
{
	GL_CLAMP_TO_EDGE,
	GL_REPEAT,
	GL_MIRRORED_REPEAT,
};

static const GLenum s_testMinFilters[] =
{
	GL_NEAREST,
	GL_LINEAR,
	GL_NEAREST_MIPMAP_NEAREST,
	GL_LINEAR_MIPMAP_NEAREST,
	GL_NEAREST_MIPMAP_LINEAR,
	GL_LINEAR_MIPMAP_LINEAR
};

static const GLenum s_testNonMipmapMinFilters[] =
{
	GL_NEAREST,
	GL_LINEAR
};

static const GLenum s_testMagFilters[] =
{
	GL_NEAREST,
	GL_LINEAR
};

static const GLenum s_cubeFaceTargets[] =
{
	GL_TEXTURE_CUBE_MAP_POSITIVE_X,
	GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
	GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
	GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
};

static string generateMultiTexFragmentShader(int numUnits, const GLenum* unitTypes)
{
	// The fragment shader calculates the average of a set of textures.

	string samplersStr;
	string matricesStr;
	string lookupsStr;

	string colorMultiplier = "(1.0/" + de::toString(numUnits) + ".0)";

	for (int ndx = 0; ndx < numUnits; ndx++)
	{
		string			ndxStr				= de::toString(ndx);
		string			samplerName			= "u_sampler" + ndxStr;
		string			transformationName	= "u_trans" + ndxStr;
		const char*		samplerType			= unitTypes[ndx] == GL_TEXTURE_2D ? "sampler2D" : "samplerCube";
		const char*		lookupFunc			= unitTypes[ndx] == GL_TEXTURE_2D ? "texture2D" : "textureCube";

		samplersStr += string("") + "uniform mediump " + samplerType + " " + samplerName + ";\n";
		matricesStr += "uniform mediump mat3 " + transformationName + ";\n";

		string lookupCoord = transformationName + "*vec3(v_coord, 1.0)";

		if (unitTypes[ndx] == GL_TEXTURE_2D)
			lookupCoord = "vec2(" + lookupCoord + ")";

		lookupsStr += "\tcolor += " + colorMultiplier + "*" + lookupFunc + "(" + samplerName + ", " + lookupCoord + ");\n";
	}

	return
		samplersStr +
		matricesStr +
		"varying mediump vec2 v_coord;\n"
		"\n"
		"void main (void)\n"
		"{\n"
		"	mediump vec4 color = vec4(0.0);\n" +
		lookupsStr +
		"	gl_FragColor = color;\n"
		"}\n";
}

static sglr::pdec::ShaderProgramDeclaration generateShaderProgramDeclaration (int numUnits, const GLenum* unitTypes)
{
	sglr::pdec::ShaderProgramDeclaration decl;

	decl << sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT);
	decl << sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT);
	decl << sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT);
	decl << sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT);

	for (int ndx = 0; ndx < numUnits; ++ndx)
	{
		string	samplerName			= "u_sampler" + de::toString(ndx);
		string	transformationName	= "u_trans" + de::toString(ndx);

		decl << sglr::pdec::Uniform(samplerName, (unitTypes[ndx] == GL_TEXTURE_2D) ? (glu::TYPE_SAMPLER_2D) : (glu::TYPE_SAMPLER_CUBE));
		decl << sglr::pdec::Uniform(transformationName, glu::TYPE_FLOAT_MAT3);
	}

	decl << sglr::pdec::VertexSource("attribute highp vec4 a_position;\n"
									 "attribute mediump vec2 a_coord;\n"
									 "varying mediump vec2 v_coord;\n"
									 "\n"
									 "void main (void)\n"
									 "{\n"
									 "	gl_Position = a_position;\n"
									 "	v_coord = a_coord;\n"
									 "}\n");
	decl << sglr::pdec::FragmentSource(generateMultiTexFragmentShader(numUnits, unitTypes));

	return decl;
}

// Calculates values to be used in calculateLod().
static Vec4 calculateLodDerivateParts(const Mat3& transformation)
{
	// Calculate transformed coordinates of three corners.
	Vec2 trans00 = (transformation * Vec3(0.0f, 0.0f, 1.0f)).xy();
	Vec2 trans01 = (transformation * Vec3(0.0f, 1.0f, 1.0f)).xy();
	Vec2 trans10 = (transformation * Vec3(1.0f, 0.0f, 1.0f)).xy();

	return Vec4(trans10.x() - trans00.x(),
				trans01.x() - trans00.x(),
				trans10.y() - trans00.y(),
				trans01.y() - trans00.y());
}

// Calculates the maximum allowed lod from derivates
static float calculateLodMax(const Vec4& derivateParts, const tcu::IVec2& textureSize, const Vec2& screenDerivate)
{
	float dudx = derivateParts.x() * (float)textureSize.x() * screenDerivate.x();
	float dudy = derivateParts.y() * (float)textureSize.x() * screenDerivate.y();
	float dvdx = derivateParts.z() * (float)textureSize.y() * screenDerivate.x();
	float dvdy = derivateParts.w() * (float)textureSize.y() * screenDerivate.y();

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

// Calculates the minimum allowed lod from derivates
static float calculateLodMin(const Vec4& derivateParts, const tcu::IVec2& textureSize, const Vec2& screenDerivate)
{
	float dudx = derivateParts.x() * (float)textureSize.x() * screenDerivate.x();
	float dudy = derivateParts.y() * (float)textureSize.x() * screenDerivate.y();
	float dvdx = derivateParts.z() * (float)textureSize.y() * screenDerivate.x();
	float dvdy = derivateParts.w() * (float)textureSize.y() * screenDerivate.y();

	return deFloatLog2(de::max(de::max(de::abs(dudx), de::abs(dudy)), de::max(de::abs(dvdx), de::abs(dvdy))));
}

class MultiTexShader : public sglr::ShaderProgram
{
public:
							MultiTexShader	(deUint32 randSeed, int numUnits, const vector<GLenum>& unitTypes);

	void					setUniforms		(sglr::Context& context, deUint32 program) const;
	void					makeSafeLods	(const vector<IVec2>& textureSizes, const IVec2& viewportSize); // Modifies texture coordinates so that LODs aren't too close to x.5 or 0.0 .

private:
	void					shadeVertices	(const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const;
	void					shadeFragments	(rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const;

	int						m_numUnits;
	vector<GLenum>			m_unitTypes;		// 2d or cube map.
	vector<Mat3>			m_transformations;
	vector<Vec4>			m_lodDerivateParts;	// Parts of lod derivates; computed in init(), used in eval().
};

MultiTexShader::MultiTexShader (deUint32 randSeed, int numUnits, const vector<GLenum>& unitTypes)
	: sglr::ShaderProgram	(generateShaderProgramDeclaration(numUnits, &unitTypes[0]))
	, m_numUnits			(numUnits)
	, m_unitTypes			(unitTypes)
{
	// 2d-to-cube-face transformations.
	// \note 2d coordinates range from 0 to 1 and cube face coordinates from -1 to 1, so scaling is done as well.
	static const float s_cubeTransforms[][3*3] =
	{
		// Face -X: (x, y, 1) -> (-1, -(2*y-1), +(2*x-1))
		{  0.0f,  0.0f, -1.0f,
		   0.0f, -2.0f,  1.0f,
		   2.0f,  0.0f, -1.0f },
		// Face +X: (x, y, 1) -> (+1, -(2*y-1), -(2*x-1))
		{  0.0f,  0.0f,  1.0f,
		   0.0f, -2.0f,  1.0f,
		  -2.0f,  0.0f,  1.0f },
		// Face -Y: (x, y, 1) -> (+(2*x-1), -1, -(2*y-1))
		{  2.0f,  0.0f, -1.0f,
		   0.0f,  0.0f, -1.0f,
		   0.0f, -2.0f,  1.0f },
		// Face +Y: (x, y, 1) -> (+(2*x-1), +1, +(2*y-1))
		{  2.0f,  0.0f, -1.0f,
		   0.0f,  0.0f,  1.0f,
		   0.0f,  2.0f, -1.0f },
		// Face -Z: (x, y, 1) -> (-(2*x-1), -(2*y-1), -1)
		{ -2.0f,  0.0f,  1.0f,
		   0.0f, -2.0f,  1.0f,
		   0.0f,  0.0f, -1.0f },
		// Face +Z: (x, y, 1) -> (+(2*x-1), -(2*y-1), +1)
		{  2.0f,  0.0f, -1.0f,
		   0.0f, -2.0f,  1.0f,
		   0.0f,  0.0f,  1.0f }
	};

	// Generate transformation matrices.

	de::Random rnd(randSeed);

	m_transformations.reserve(m_numUnits);
	m_lodDerivateParts.reserve(m_numUnits);

	DE_ASSERT((int)m_unitTypes.size() == m_numUnits);

	for (int unitNdx = 0; unitNdx < m_numUnits; unitNdx++)
	{
		if (m_unitTypes[unitNdx] == GL_TEXTURE_2D)
		{
			float rotAngle				= rnd.getFloat(0.0f, 2.0f*DE_PI);
			float xScaleFactor			= rnd.getFloat(0.7f, 1.5f);
			float yScaleFactor			= rnd.getFloat(0.7f, 1.5f);
			float xShearAmount			= rnd.getFloat(0.0f, 0.5f);
			float yShearAmount			= rnd.getFloat(0.0f, 0.5f);
			float xTranslationAmount	= rnd.getFloat(-0.5f, 0.5f);
			float yTranslationAmount	= rnd.getFloat(-0.5f, 0.5f);

			float tempOffsetData[3*3] = // For temporarily centering the coordinates to get nicer transformations.
			{
				1.0f,  0.0f, -0.5f,
				0.0f,  1.0f, -0.5f,
				0.0f,  0.0f,  1.0f
			};
			float rotTransfData[3*3] =
			{
				deFloatCos(rotAngle),	-deFloatSin(rotAngle),	0.0f,
				deFloatSin(rotAngle),	deFloatCos(rotAngle),	0.0f,
				0.0f,					0.0f,					1.0f
			};
			float scaleTransfData[3*3] =
			{
				xScaleFactor,	0.0f,			0.0f,
				0.0f,			yScaleFactor,	0.0f,
				0.0f,			0.0f,			1.0f
			};
			float xShearTransfData[3*3] =
			{
				1.0f,			xShearAmount,	0.0f,
				0.0f,			1.0f,			0.0f,
				0.0f,			0.0f,			1.0f
			};
			float yShearTransfData[3*3] =
			{
				1.0f,			0.0f,			0.0f,
				yShearAmount,	1.0f,			0.0f,
				0.0f,			0.0f,			1.0f
			};
			float translationTransfData[3*3] =
			{
				1.0f,	0.0f,	xTranslationAmount,
				0.0f,	1.0f,	yTranslationAmount,
				0.0f,	0.0f,	1.0f
			};

			Mat3 transformation =
				Mat3(tempOffsetData) *
				Mat3(translationTransfData) *
				Mat3(rotTransfData) *
				Mat3(scaleTransfData) *
				Mat3(xShearTransfData) *
				Mat3(yShearTransfData) *
				(Mat3(tempOffsetData) * (-1.0f));

			// Calculate parts of lod derivates.
			m_lodDerivateParts.push_back(calculateLodDerivateParts(transformation));

			m_transformations.push_back(transformation);
		}
		else
		{
			DE_ASSERT(m_unitTypes[unitNdx] == GL_TEXTURE_CUBE_MAP);
			DE_STATIC_ASSERT((int)tcu::CUBEFACE_LAST == DE_LENGTH_OF_ARRAY(s_cubeTransforms));

			float planarTransData[3*3];

			// In case of a cube map, we only want to render one face, so the transformation needs to be restricted - only enlarging scaling is done.

			for (int i = 0; i < DE_LENGTH_OF_ARRAY(planarTransData); i++)
			{
				if (i == 0 || i == 4)
					planarTransData[i] = rnd.getFloat(0.1f, 0.9f); // Two first diagonal cells control the scaling.
				else if (i == 8)
					planarTransData[i] = 1.0f;
				else
					planarTransData[i] = 0.0f;
			}

			int		faceNdx			= rnd.getInt(0, (int)tcu::CUBEFACE_LAST - 1);
			Mat3	planarTrans		(planarTransData);									// Planar, face-agnostic transformation.
			Mat3	finalTrans		= Mat3(s_cubeTransforms[faceNdx]) * planarTrans;	// Final transformation from planar to cube map coordinates, including the transformation just generated.

			// Calculate parts of lod derivates.
			m_lodDerivateParts.push_back(calculateLodDerivateParts(planarTrans));

			m_transformations.push_back(finalTrans);
		}
	}
}

void MultiTexShader::setUniforms (sglr::Context& ctx, deUint32 program) const
{
	ctx.useProgram(program);

	// Sampler and matrix uniforms.

	for (int ndx = 0; ndx < m_numUnits; ndx++)
	{
		string			ndxStr		= de::toString(ndx);

		ctx.uniform1i(ctx.getUniformLocation(program, ("u_sampler" + ndxStr).c_str()), ndx);
		ctx.uniformMatrix3fv(ctx.getUniformLocation(program, ("u_trans" + ndxStr).c_str()), 1, GL_FALSE, (GLfloat*)&m_transformations[ndx].getColumnMajorData()[0]);
	}
}

void MultiTexShader::makeSafeLods (const vector<IVec2>& textureSizes, const IVec2& viewportSize)
{
	DE_ASSERT((int)textureSizes.size() == m_numUnits);

	static const float shrinkScaleMatData[3*3] =
	{
		0.95f,	0.0f,	0.0f,
		0.0f,	0.95f,	0.0f,
		0.0f,	0.0f,	1.0f
	};
	Mat3 shrinkScaleMat(shrinkScaleMatData);

	Vec2 screenDerivate(1.0f / (float)viewportSize.x(), 1.0f / (float)viewportSize.y());

	for (int unitNdx = 0; unitNdx < m_numUnits; unitNdx++)
	{
		// As long as LOD is too close to 0.0 or is positive and too close to a something-and-a-half (0.5, 1.5, 2.5 etc) or allowed lod range could round to different levels, zoom in a little to get a safer LOD.
		for (;;)
		{
			const float threshold = 0.1f;
			const float epsilon	= 0.01f;

			const float lodMax = calculateLodMax(m_lodDerivateParts[unitNdx], textureSizes[unitNdx], screenDerivate);
			const float lodMin = calculateLodMin(m_lodDerivateParts[unitNdx], textureSizes[unitNdx], screenDerivate);

			const deInt32 maxLevel = (lodMax + epsilon < 0.5f) ? (0) : (deCeilFloatToInt32(lodMax + epsilon + 0.5f) - 1);
			const deInt32 minLevel = (lodMin - epsilon < 0.5f) ? (0) : (deCeilFloatToInt32(lodMin - epsilon + 0.5f) - 1);

			if (de::abs(lodMax) < threshold || (lodMax > 0.0f && de::abs(deFloatFrac(lodMax) - 0.5f) < threshold) ||
				de::abs(lodMin) < threshold || (lodMin > 0.0f && de::abs(deFloatFrac(lodMin) - 0.5f) < threshold) ||
				maxLevel != minLevel)
			{
				m_transformations[unitNdx] = shrinkScaleMat * m_transformations[unitNdx];
				m_lodDerivateParts[unitNdx] = calculateLodDerivateParts(m_transformations[unitNdx]);
			}
			else
				break;
		}
	}
}

void MultiTexShader::shadeVertices (const rr::VertexAttrib* inputs, rr::VertexPacket* const* packets, const int numPackets) const
{
	for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
	{
		rr::VertexPacket& packet = *(packets[packetNdx]);

		packet.position		= rr::readVertexAttribFloat(inputs[0], packet.instanceNdx, packet.vertexNdx);
		packet.outputs[0]	= rr::readVertexAttribFloat(inputs[1], packet.instanceNdx, packet.vertexNdx);
	}
}

void MultiTexShader::shadeFragments	(rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
{
	DE_ASSERT((int)m_unitTypes.size() == m_numUnits);
	DE_ASSERT((int)m_transformations.size() == m_numUnits);
	DE_ASSERT((int)m_lodDerivateParts.size() == m_numUnits);

	for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
	{
		rr::FragmentPacket& packet				= packets[packetNdx];
		const float			colorMultiplier		= 1.0f / (float)m_numUnits;
		Vec4				outColors[4]		= { Vec4(0.0f), Vec4(0.0f), Vec4(0.0f), Vec4(0.0f) };

		for (int unitNdx = 0; unitNdx < m_numUnits; unitNdx++)
		{
			tcu::Vec4 texSamples[4];

			// Read tex coords
			const tcu::Vec2 texCoords[4] =
			{
				rr::readTriangleVarying<float>(packet, context, 0, 0).xy(),
				rr::readTriangleVarying<float>(packet, context, 0, 1).xy(),
				rr::readTriangleVarying<float>(packet, context, 0, 2).xy(),
				rr::readTriangleVarying<float>(packet, context, 0, 3).xy(),
			};

			if (m_unitTypes[unitNdx] == GL_TEXTURE_2D)
			{
				// Transform
				const tcu::Vec2 transformedTexCoords[4] =
				{
					(m_transformations[unitNdx] * Vec3(texCoords[0].x(), texCoords[0].y(), 1.0f)).xy(),
					(m_transformations[unitNdx] * Vec3(texCoords[1].x(), texCoords[1].y(), 1.0f)).xy(),
					(m_transformations[unitNdx] * Vec3(texCoords[2].x(), texCoords[2].y(), 1.0f)).xy(),
					(m_transformations[unitNdx] * Vec3(texCoords[3].x(), texCoords[3].y(), 1.0f)).xy(),
				};

				// Sample
				m_uniforms[2*unitNdx].sampler.tex2D->sample4(texSamples, transformedTexCoords);
			}
			else
			{
				DE_ASSERT(m_unitTypes[unitNdx] == GL_TEXTURE_CUBE_MAP);

				// Transform
				const tcu::Vec3 transformedTexCoords[4] =
				{
					m_transformations[unitNdx] * Vec3(texCoords[0].x(), texCoords[0].y(), 1.0f),
					m_transformations[unitNdx] * Vec3(texCoords[1].x(), texCoords[1].y(), 1.0f),
					m_transformations[unitNdx] * Vec3(texCoords[2].x(), texCoords[2].y(), 1.0f),
					m_transformations[unitNdx] * Vec3(texCoords[3].x(), texCoords[3].y(), 1.0f),
				};

				// Sample
				m_uniforms[2*unitNdx].sampler.texCube->sample4(texSamples, transformedTexCoords);
			}

			// Add to sum
			for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
				outColors[fragNdx] += colorMultiplier * texSamples[fragNdx];
		}

		// output
		for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
			rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, outColors[fragNdx]);
	}
}

class TextureUnitCase : public TestCase
{
public:
	enum CaseType
	{
		CASE_ONLY_2D = 0,
		CASE_ONLY_CUBE,
		CASE_MIXED,

		CASE_LAST
	};
								TextureUnitCase		(Context& context, const char* name, const char* desc, int numUnits /* \note If non-positive, use all units */, CaseType caseType, deUint32 randSeed);
								~TextureUnitCase	(void);

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

private:
	struct TextureParameters
	{
		GLenum format;
		GLenum dataType;
		GLenum wrapModeS;
		GLenum wrapModeT;
		GLenum minFilter;
		GLenum magFilter;
	};

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

	void						render				(sglr::Context& context);

	const int					m_numUnitsParam;
	const CaseType				m_caseType;
	const deUint32				m_randSeed;

	int							m_numTextures;	//!< \note Needed in addition to m_numUnits since same texture may be bound to many texture units.
	int							m_numUnits;		//!< = m_numUnitsParam > 0 ? m_numUnitsParam : implementationDefinedMaximum

	vector<GLenum>				m_textureTypes;
	vector<TextureParameters>	m_textureParams;
	vector<tcu::Texture2D*>		m_textures2d;
	vector<tcu::TextureCube*>	m_texturesCube;
	vector<int>					m_unitTextures;	//!< Which texture is used in a particular unit.
	vector<int>					m_ndx2dOrCube;	//!< Index of a texture in either m_textures2d or m_texturesCube, depending on texture type.
	MultiTexShader*				m_shader;
};

TextureUnitCase::TextureUnitCase (Context& context, const char* name, const char* desc, int numUnits, CaseType caseType, deUint32 randSeed)
	: TestCase			(context, tcu::NODETYPE_SELF_VALIDATE, name, desc)
	, m_numUnitsParam	(numUnits)
	, m_caseType		(caseType)
	, m_randSeed		(randSeed)
	, m_shader			(DE_NULL)
{
}

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

void TextureUnitCase::deinit (void)
{
	for (vector<tcu::Texture2D*>::iterator i = m_textures2d.begin(); i != m_textures2d.end(); i++)
		delete *i;
	m_textures2d.clear();

	for (vector<tcu::TextureCube*>::iterator i = m_texturesCube.begin(); i != m_texturesCube.end(); i++)
		delete *i;
	m_texturesCube.clear();

	delete m_shader;
	m_shader = DE_NULL;
}

void TextureUnitCase::init (void)
{
	m_numUnits = m_numUnitsParam > 0 ? m_numUnitsParam : m_context.getContextInfo().getInt(GL_MAX_TEXTURE_IMAGE_UNITS);

	// Make the textures.

	try
	{
		tcu::TestLog&	log	= m_testCtx.getLog();
		de::Random		rnd	(m_randSeed);

		if (rnd.getFloat() < 0.7f)
			m_numTextures = m_numUnits;											// In most cases use one unit per texture.
		else
			m_numTextures = rnd.getInt(deMax32(1, m_numUnits - 2), m_numUnits);	// Sometimes assign same texture to multiple units.

		log << tcu::TestLog::Message << ("Using " + de::toString(m_numUnits) + " texture unit(s) and " + de::toString(m_numTextures) + " texture(s)").c_str() << tcu::TestLog::EndMessage;

		m_textureTypes.reserve(m_numTextures);
		m_textureParams.reserve(m_numTextures);
		m_ndx2dOrCube.reserve(m_numTextures);

		// Generate textures.

		for (int texNdx = 0; texNdx < m_numTextures; texNdx++)
		{
			// Either fixed or randomized target types (2d or cube), and randomized parameters for every texture.

			TextureParameters	params;
			bool				is2d		= m_caseType == CASE_ONLY_2D	? true :
											  m_caseType == CASE_ONLY_CUBE	? false :
																			  rnd.getBool();

			GLenum				type		= is2d ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP;
			const int			texWidth	= is2d ? TEXTURE_WIDTH_2D : TEXTURE_WIDTH_CUBE;
			const int			texHeight	= is2d ? TEXTURE_HEIGHT_2D : TEXTURE_HEIGHT_CUBE;
			bool				mipmaps		= (deIsPowerOfTwo32(texWidth) && deIsPowerOfTwo32(texHeight));
			int					numLevels	= mipmaps ? deLog2Floor32(de::max(texWidth, texHeight))+1 : 1;

			params.wrapModeS	= s_testWrapModes	[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_testWrapModes) - 1)];
			params.wrapModeT	= s_testWrapModes	[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_testWrapModes) - 1)];
			params.magFilter	= s_testMagFilters	[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_testMagFilters) - 1)];
			params.dataType		= s_testDataTypes	[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_testDataTypes) - 1)];

			// Certain minification filters are only used when using mipmaps.
			if (mipmaps)
				params.minFilter = s_testMinFilters[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_testMinFilters) - 1)];
			else
				params.minFilter = s_testNonMipmapMinFilters[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_testNonMipmapMinFilters) - 1)];

			// Format may depend on data type.
			if (params.dataType == GL_UNSIGNED_SHORT_5_6_5)
				params.format = GL_RGB;
			else if (params.dataType == GL_UNSIGNED_SHORT_4_4_4_4 || params.dataType == GL_UNSIGNED_SHORT_5_5_5_1)
				params.format = GL_RGBA;
			else
				params.format = s_testFormats[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_testFormats) - 1)];

			m_textureTypes.push_back(type);
			m_textureParams.push_back(params);

			// Create new texture.

			if (is2d)
			{
				m_ndx2dOrCube.push_back((int)m_textures2d.size()); // Remember the index this texture has in the 2d array.
				m_textures2d.push_back(new tcu::Texture2D(glu::mapGLTransferFormat(params.format, params.dataType), texWidth, texHeight));
			}
			else
			{
				m_ndx2dOrCube.push_back((int)m_texturesCube.size()); // Remember the index this texture has in the cube array.
				DE_ASSERT(texWidth == texHeight);
				m_texturesCube.push_back(new tcu::TextureCube(glu::mapGLTransferFormat(params.format, params.dataType), texWidth));
			}

			tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(is2d ? m_textures2d.back()->getFormat() : m_texturesCube.back()->getFormat());
			Vec4					cBias		= fmtInfo.valueMin;
			Vec4					cScale		= fmtInfo.valueMax-fmtInfo.valueMin;

			// Fill with grid texture.

			int numFaces = is2d ? 1 : (int)tcu::CUBEFACE_LAST;

			for (int face = 0; face < numFaces; face++)
			{
				deUint32 rgb	= rnd.getUint32() & 0x00ffffff;
				deUint32 alpha0	= 0xff000000;
				deUint32 alpha1	= 0xff000000;

				if (params.format == GL_ALPHA) // \note This needs alpha to be visible.
				{
					alpha0 &= rnd.getUint32();
					alpha1 = ~alpha0;
				}

				deUint32 colorA = alpha0 | rgb;
				deUint32 colorB = alpha1 | ~rgb;

				for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
				{
					if (is2d)
						m_textures2d.back()->allocLevel(levelNdx);
					else
						m_texturesCube.back()->allocLevel((tcu::CubeFace)face, levelNdx);

					int curCellSize = deMax32(1, GRID_CELL_SIZE >> levelNdx); // \note Scale grid cell size for mipmaps.

					tcu::PixelBufferAccess access = is2d ? m_textures2d.back()->getLevel(levelNdx) : m_texturesCube.back()->getLevelFace(levelNdx, (tcu::CubeFace)face);
					tcu::fillWithGrid(access, curCellSize, tcu::RGBA(colorA).toVec()*cScale + cBias, tcu::RGBA(colorB).toVec()*cScale + cBias);
				}
			}
		}

		// Assign a texture index to each unit.

		m_unitTextures.reserve(m_numUnits);

		// \note Every texture is used at least once.
		for (int i = 0; i < m_numTextures; i++)
			m_unitTextures.push_back(i);

		// Assign a random texture to remaining units.
		while ((int)m_unitTextures.size() < m_numUnits)
			m_unitTextures.push_back(rnd.getInt(0, m_numTextures - 1));

		rnd.shuffle(m_unitTextures.begin(), m_unitTextures.end());

		// Create shader.

		vector<GLenum> unitTypes;
		unitTypes.reserve(m_numUnits);
		for (int i = 0; i < m_numUnits; i++)
			unitTypes.push_back(m_textureTypes[m_unitTextures[i]]);

		DE_ASSERT(m_shader == DE_NULL);
		m_shader = new MultiTexShader(rnd.getUint32(), m_numUnits, unitTypes);
	}
	catch (const std::exception&)
	{
		// Clean up to save memory.
		TextureUnitCase::deinit();
		throw;
	}
}

TextureUnitCase::IterateResult TextureUnitCase::iterate (void)
{
	glu::RenderContext&			renderCtx			= m_context.getRenderContext();
	const tcu::RenderTarget&	renderTarget		= renderCtx.getRenderTarget();
	tcu::TestLog&				log					= m_testCtx.getLog();
	de::Random					rnd					(m_randSeed);

	int							viewportWidth		= deMin32(VIEWPORT_WIDTH, renderTarget.getWidth());
	int							viewportHeight		= deMin32(VIEWPORT_HEIGHT, renderTarget.getHeight());
	int							viewportX			= rnd.getInt(0, renderTarget.getWidth() - viewportWidth);
	int							viewportY			= rnd.getInt(0, renderTarget.getHeight() - viewportHeight);

	tcu::Surface				gles2Frame			(viewportWidth, viewportHeight);
	tcu::Surface				refFrame			(viewportWidth, viewportHeight);

	{
		// First we do some tricks to make the LODs safer wrt. precision issues. See MultiTexShader::makeSafeLods().

		vector<IVec2> texSizes;
		texSizes.reserve(m_numUnits);

		for (int i = 0; i < m_numUnits; i++)
		{
			int		texNdx			= m_unitTextures[i];
			int		texNdxInType	= m_ndx2dOrCube[texNdx];
			GLenum	type			= m_textureTypes[texNdx];

			switch (type)
			{
				case GL_TEXTURE_2D:			texSizes.push_back(IVec2(m_textures2d[texNdxInType]->getWidth(),	m_textures2d[texNdxInType]->getHeight()));	break;
				case GL_TEXTURE_CUBE_MAP:	texSizes.push_back(IVec2(m_texturesCube[texNdxInType]->getSize(),	m_texturesCube[texNdxInType]->getSize()));	break;
				default:
					DE_ASSERT(DE_FALSE);
			}
		}

		m_shader->makeSafeLods(texSizes, IVec2(viewportWidth, viewportHeight));
	}

	// Render using GLES2.
	{
		sglr::GLContext context(renderCtx, log, sglr::GLCONTEXT_LOG_CALLS|sglr::GLCONTEXT_LOG_PROGRAMS, tcu::IVec4(viewportX, viewportY, viewportWidth, viewportHeight));

		render(context);

		context.readPixels(gles2Frame, 0, 0, viewportWidth, viewportHeight);
	}

	// Render reference image.
	{
		sglr::ReferenceContextBuffers	buffers	(tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), 0 /* depth */, 0 /* stencil */, viewportWidth, viewportHeight);
		sglr::ReferenceContext			context	(sglr::ReferenceContextLimits(renderCtx), buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer());

		render(context);

		context.readPixels(refFrame, 0, 0, viewportWidth, viewportHeight);
	}

	// Compare images.
	const float		threshold	= 0.001f;
	bool			isOk		= tcu::fuzzyCompare(log, "ComparisonResult", "Image comparison result", refFrame, gles2Frame, threshold, tcu::COMPARE_LOG_RESULT);

	// Store test result.
	m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
							isOk ? "Pass"				: "Image comparison failed");

	return STOP;
}

void TextureUnitCase::render (sglr::Context& context)
{
	// Setup textures.

	vector<deUint32>	textureGLNames;
	vector<bool>		isTextureSetUp(m_numTextures, false); // \note Same texture may be bound to multiple units, but we only want to set up parameters and data once per texture.

	textureGLNames.resize(m_numTextures);
	context.genTextures(m_numTextures, &textureGLNames[0]);

	for (int unitNdx = 0; unitNdx < m_numUnits; unitNdx++)
	{
		int texNdx = m_unitTextures[unitNdx];

		// Bind texture to unit.
		context.activeTexture(GL_TEXTURE0 + unitNdx);
		context.bindTexture(m_textureTypes[texNdx], textureGLNames[texNdx]);

		if (!isTextureSetUp[texNdx])
		{
			// Binding this texture for first time, so set parameters and data.

			context.texParameteri(m_textureTypes[texNdx], GL_TEXTURE_WRAP_S, m_textureParams[texNdx].wrapModeS);
			context.texParameteri(m_textureTypes[texNdx], GL_TEXTURE_WRAP_T, m_textureParams[texNdx].wrapModeT);
			context.texParameteri(m_textureTypes[texNdx], GL_TEXTURE_MIN_FILTER, m_textureParams[texNdx].minFilter);
			context.texParameteri(m_textureTypes[texNdx], GL_TEXTURE_MAG_FILTER, m_textureParams[texNdx].magFilter);

			if (m_textureTypes[texNdx] == GL_TEXTURE_2D)
			{
				int						ndx2d		= m_ndx2dOrCube[texNdx];
				const tcu::Texture2D*	texture		= m_textures2d[ndx2d];
				bool					mipmaps		= (deIsPowerOfTwo32(texture->getWidth()) && deIsPowerOfTwo32(texture->getHeight()));
				int						numLevels	= mipmaps ? deLog2Floor32(de::max(texture->getWidth(), texture->getHeight()))+1 : 1;

				context.pixelStorei(GL_UNPACK_ALIGNMENT, 1);

				for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
				{
					tcu::ConstPixelBufferAccess		access	= texture->getLevel(levelNdx);
					int								width	= access.getWidth();
					int								height	= access.getHeight();

					DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*width);

					context.texImage2D(GL_TEXTURE_2D, levelNdx, m_textureParams[texNdx].format, width, height, 0, m_textureParams[texNdx].format, m_textureParams[texNdx].dataType, access.getDataPtr());
				}
			}
			else
			{
				DE_ASSERT(m_textureTypes[texNdx] == GL_TEXTURE_CUBE_MAP);

				int							ndxCube		= m_ndx2dOrCube[texNdx];
				const tcu::TextureCube*		texture		= m_texturesCube[ndxCube];
				bool						mipmaps		= deIsPowerOfTwo32(texture->getSize()) != DE_FALSE;
				int							numLevels	= mipmaps ? deLog2Floor32(texture->getSize())+1 : 1;

				context.pixelStorei(GL_UNPACK_ALIGNMENT, 1);

				for (int face = 0; face < (int)tcu::CUBEFACE_LAST; face++)
				{
					for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
					{
						tcu::ConstPixelBufferAccess		access	= texture->getLevelFace(levelNdx, (tcu::CubeFace)face);
						int								width	= access.getWidth();
						int								height	= access.getHeight();

						DE_ASSERT(access.getRowPitch() == access.getFormat().getPixelSize()*width);

						context.texImage2D(s_cubeFaceTargets[face], levelNdx, m_textureParams[texNdx].format, width, height, 0, m_textureParams[texNdx].format, m_textureParams[texNdx].dataType, access.getDataPtr());
					}
				}
			}

			isTextureSetUp[texNdx] = true; // Don't set up this texture's parameters and data again later.
		}
	}

	GLU_EXPECT_NO_ERROR(context.getError(), "Set textures");

	// Setup shader

	deUint32 shaderID = context.createProgram(m_shader);

	// Draw.

	context.clearColor(0.125f, 0.25f, 0.5f, 1.0f);
	context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
	m_shader->setUniforms(context, shaderID);
	sglr::drawQuad(context, shaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
	GLU_EXPECT_NO_ERROR(context.getError(), "Draw");

	// Delete previously generated texture names.

	context.deleteTextures(m_numTextures, &textureGLNames[0]);
	GLU_EXPECT_NO_ERROR(context.getError(), "Delete textures");
}

TextureUnitTests::TextureUnitTests (Context& context)
	: TestCaseGroup(context, "units", "Texture Unit Usage Tests")
{
}

TextureUnitTests::~TextureUnitTests (void)
{
}

void TextureUnitTests::init (void)
{
	const int numTestsPerGroup = 10;

	static const int unitCounts[] =
	{
		2,
		4,
		8,
		-1 // \note Negative stands for the implementation-specified maximum.
	};

	for (int unitCountNdx = 0; unitCountNdx < DE_LENGTH_OF_ARRAY(unitCounts); unitCountNdx++)
	{
		int numUnits = unitCounts[unitCountNdx];

		string countGroupName = (unitCounts[unitCountNdx] < 0 ? "all" : de::toString(numUnits)) + "_units";

		tcu::TestCaseGroup* countGroup = new tcu::TestCaseGroup(m_testCtx, countGroupName.c_str(), "");
		addChild(countGroup);

		DE_STATIC_ASSERT((int)TextureUnitCase::CASE_ONLY_2D == 0);

		for (int caseType = (int)TextureUnitCase::CASE_ONLY_2D; caseType < (int)TextureUnitCase::CASE_LAST; caseType++)
		{
			const char* caseTypeGroupName = (TextureUnitCase::CaseType)caseType == TextureUnitCase::CASE_ONLY_2D	? "only_2d" :
											(TextureUnitCase::CaseType)caseType == TextureUnitCase::CASE_ONLY_CUBE	? "only_cube" :
											(TextureUnitCase::CaseType)caseType == TextureUnitCase::CASE_MIXED		? "mixed" :
																													  DE_NULL;
			DE_ASSERT(caseTypeGroupName != DE_NULL);

			tcu::TestCaseGroup* caseTypeGroup = new tcu::TestCaseGroup(m_testCtx, caseTypeGroupName, "");
			countGroup->addChild(caseTypeGroup);

			for (int testNdx = 0; testNdx < numTestsPerGroup; testNdx++)
				caseTypeGroup->addChild(new TextureUnitCase(m_context, de::toString(testNdx).c_str(), "", numUnits, (TextureUnitCase::CaseType)caseType, (deUint32)deInt32Hash(testNdx)));
		}
	}
}

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