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

#include "es3fTextureUnitTests.hpp"
#include "glsTextureTestUtil.hpp"
#include "gluTextureUtil.hpp"
#include "gluContextInfo.hpp"
#include "gluTextureUtil.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 "deRandom.hpp"
#include "deStringUtil.hpp"

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

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

namespace deqp
{

using namespace gls::TextureTestUtil;

namespace gles3
{
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 TEXTURE_WIDTH_2D_ARRAY		= 64;
static const int TEXTURE_HEIGHT_2D_ARRAY	= 64;
static const int TEXTURE_LAYERS_2D_ARRAY	= 4;

static const int TEXTURE_WIDTH_3D			= 32;
static const int TEXTURE_HEIGHT_3D			= 32;
static const int TEXTURE_DEPTH_3D			= 32;

static const int GRID_CELL_SIZE				= 8;

static const GLenum s_testSizedInternalFormats[] =
{
	GL_RGBA32F,
	GL_RGBA32I,
	GL_RGBA32UI,
	GL_RGBA16F,
	GL_RGBA16I,
	GL_RGBA16UI,
	GL_RGBA8,
	GL_RGBA8I,
	GL_RGBA8UI,
	GL_SRGB8_ALPHA8,
	GL_RGB10_A2,
	GL_RGB10_A2UI,
	GL_RGBA4,
	GL_RGB5_A1,
	GL_RGBA8_SNORM,
	GL_RGB8,
	GL_RGB565,
	GL_R11F_G11F_B10F,
	GL_RGB32F,
	GL_RGB32I,
	GL_RGB32UI,
	GL_RGB16F,
	GL_RGB16I,
	GL_RGB16UI,
	GL_RGB8_SNORM,
	GL_RGB8I,
	GL_RGB8UI,
	GL_SRGB8,
	GL_RGB9_E5,
	GL_RG32F,
	GL_RG32I,
	GL_RG32UI,
	GL_RG16F,
	GL_RG16I,
	GL_RG16UI,
	GL_RG8,
	GL_RG8I,
	GL_RG8UI,
	GL_RG8_SNORM,
	GL_R32F,
	GL_R32I,
	GL_R32UI,
	GL_R16F,
	GL_R16I,
	GL_R16UI,
	GL_R8,
	GL_R8I,
	GL_R8UI,
	GL_R8_SNORM
};

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_testNearestMinFilters[] =
{
	GL_NEAREST,
	GL_NEAREST_MIPMAP_NEAREST
};

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

// Extend a 3x3 transformation matrix to an equivalent 4x4 transformation matrix (i.e. 1.0 in right-down cell, 0.0's in other new cells).
static Mat4 matExtend3To4 (const Mat3& mat)
{
	Mat4 res;
	for (int rowNdx = 0; rowNdx < 3; rowNdx++)
	{
		Vec3 row = mat.getRow(rowNdx);
		res.setRow(rowNdx, Vec4(row.x(), row.y(), row.z(), 0.0f));
	}
	res.setRow(3, Vec4(0.0f, 0.0f, 0.0f, 1.0f));

	return res;
}

static string generateMultiTexFragmentShader (int numUnits, const vector<GLenum>& unitTypes, const vector<glu::DataType>& samplerTypes)
{
	// The fragment shader calculates the average of a set of textures.

	string samplersStr;
	string matricesStr;
	string scalesStr;
	string biasesStr;
	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;
		string scaleName			= "u_texScale" + ndxStr;
		string biasName				= "u_texBias" + ndxStr;

		samplersStr += string("") + "uniform highp " + glu::getDataTypeName(samplerTypes[ndx]) + " " + samplerName + ";\n";
		matricesStr += "uniform highp mat4 " + transformationName + ";\n";
		scalesStr += "uniform highp vec4 " + scaleName + ";\n";
		biasesStr += "uniform highp vec4 " + biasName + ";\n";

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

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

		lookupsStr += "\tcolor += " + colorMultiplier + "*(vec4(texture(" + samplerName + ", " + lookupCoord + "))*" + scaleName + " + " + biasName + ");\n";
	}

	return "#version 300 es\n"
		   "layout(location = 0) out mediump vec4 o_color;\n" +
		   samplersStr +
		   matricesStr +
		   scalesStr +
		   biasesStr +
		   "in highp vec2 v_coord;\n"
		   "\n"
		   "void main (void)\n"
		   "{\n"
		   "	mediump vec4 color = vec4(0.0);\n" +
		   lookupsStr +
		   "	o_color = color;\n"
		   "}\n";
}

static sglr::pdec::ShaderProgramDeclaration generateShaderProgramDeclaration (int numUnits, const vector<GLenum>& unitTypes, const vector<glu::DataType>& samplerTypes)
{
	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);
		string scaleName			= "u_texScale" + de::toString(ndx);
		string biasName				= "u_texBias" + de::toString(ndx);

		decl << sglr::pdec::Uniform(samplerName, samplerTypes[ndx]);
		decl << sglr::pdec::Uniform(transformationName, glu::TYPE_FLOAT_MAT4);
		decl << sglr::pdec::Uniform(scaleName, glu::TYPE_FLOAT_VEC4);
		decl << sglr::pdec::Uniform(biasName, glu::TYPE_FLOAT_VEC4);
	}

	decl << sglr::pdec::VertexSource("#version 300 es\n"
									 "in highp vec4 a_position;\n"
									 "in highp vec2 a_coord;\n"
									 "out highp 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, samplerTypes));

	return decl;
}

// Calculates values that will be used in calculateLod().
static tcu::Vector<tcu::Vec2, 3> calculateLodDerivateParts (const Mat4& transformation)
{
	// Calculate transformed coordinates of three screen corners.
	Vec3 trans00 = (transformation * Vec4(0.0f, 0.0f, 1.0f, 1.0f)).xyz();
	Vec3 trans01 = (transformation * Vec4(0.0f, 1.0f, 1.0f, 1.0f)).xyz();
	Vec3 trans10 = (transformation * Vec4(1.0f, 0.0f, 1.0f, 1.0f)).xyz();

	return tcu::Vector<tcu::Vec2, 3>(Vec2(trans10.x() - trans00.x(), trans01.x() - trans00.x()),
									 Vec2(trans10.y() - trans00.y(), trans01.y() - trans00.y()),
									 Vec2(trans10.z() - trans00.z(), trans01.z() - trans00.z()));
}

// Calculates the maximum allowed lod from derivates
static float calculateLodMax(const tcu::Vector<tcu::Vec2, 3>& derivateParts, const tcu::IVec3& textureSize, const Vec2& screenDerivate)
{
	float dudx = derivateParts[0].x() * (float)textureSize.x() * screenDerivate.x();
	float dudy = derivateParts[0].y() * (float)textureSize.x() * screenDerivate.y();
	float dvdx = derivateParts[1].x() * (float)textureSize.y() * screenDerivate.x();
	float dvdy = derivateParts[1].y() * (float)textureSize.y() * screenDerivate.y();
	float dwdx = derivateParts[2].x() * (float)textureSize.z() * screenDerivate.x();
	float dwdy = derivateParts[2].y() * (float)textureSize.z() * screenDerivate.y();

	const float mu = de::max(de::abs(dudx), de::abs(dudy));
	const float mv = de::max(de::abs(dvdx), de::abs(dvdy));
	const float mw = de::max(de::abs(dwdx), de::abs(dwdy));
	return deFloatLog2(mu + mv + mw);
}

// Calculates the minimum allowed lod from derivates
static float calculateLodMin(const tcu::Vector<tcu::Vec2, 3>& derivateParts, const tcu::IVec3& textureSize, const Vec2& screenDerivate)
{
	float dudx = derivateParts[0].x() * (float)textureSize.x() * screenDerivate.x();
	float dudy = derivateParts[0].y() * (float)textureSize.x() * screenDerivate.y();
	float dvdx = derivateParts[1].x() * (float)textureSize.y() * screenDerivate.x();
	float dvdy = derivateParts[1].y() * (float)textureSize.y() * screenDerivate.y();
	float dwdx = derivateParts[2].x() * (float)textureSize.z() * screenDerivate.x();
	float dwdy = derivateParts[2].y() * (float)textureSize.z() * screenDerivate.y();

	const float mu = de::max(de::abs(dudx), de::abs(dudy));
	const float mv = de::max(de::abs(dvdx), de::abs(dvdy));
	const float mw = de::max(de::abs(dwdx), de::abs(dwdy));
	return deFloatLog2(de::max(mu, de::max(mv, mw)));
}

class MultiTexShader : public sglr::ShaderProgram
{
public:
							MultiTexShader	(deUint32 randSeed,
											 int numUnits,
											 const vector<GLenum>& unitTypes,
											 const vector<glu::DataType>& samplerTypes,
											 const vector<Vec4>& texScales,
											 const vector<Vec4>& texBiases,
											 const vector<int>& num2dArrayLayers); // \note 2d array layer "coordinate" isn't normalized, so this is needed here.

	void					setUniforms		(sglr::Context& context, deUint32 program) const;
	void					makeSafeLods	(const vector<IVec3>& 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, cube map, 2d array or 3d.
	vector<Vec4>						m_texScales;
	vector<Vec4>						m_texBiases;
	vector<Mat4>						m_transformations;
	vector<tcu::Vector<tcu::Vec2, 3> >	m_lodDerivateParts;	// Parts of lod derivates; computed in init(), used in eval().
};

MultiTexShader::MultiTexShader (deUint32 randSeed,
								int numUnits,
								const vector<GLenum>& unitTypes,
								const vector<glu::DataType>& samplerTypes,
								const vector<Vec4>& texScales,
								const vector<Vec4>& texBiases,
								const vector<int>& num2dArrayLayers)
		: sglr::ShaderProgram	(generateShaderProgramDeclaration(numUnits, unitTypes, samplerTypes))
		, m_numUnits		(numUnits)
		, m_unitTypes		(unitTypes)
		, m_texScales		(texScales)
		, m_texBiases		(texBiases)
{
	// 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);

	int tex2dArrayNdx = 0; // Keep track of 2d texture array index.

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

			static const 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
			};

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

			m_lodDerivateParts.push_back(calculateLodDerivateParts(transformation));
			m_transformations.push_back(transformation);
		}
		else if (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.
			Mat4	finalTrans		= matExtend3To4(Mat3(s_cubeTransforms[faceNdx]) * planarTrans);	// Final transformation from planar to cube map coordinates, including the transformation just generated.
			Mat4	planarTrans4x4	= matExtend3To4(planarTrans);

			m_lodDerivateParts.push_back(calculateLodDerivateParts(planarTrans4x4));
			m_transformations.push_back(finalTrans);
		}
		else
		{
			DE_ASSERT(m_unitTypes[unitNdx] == GL_TEXTURE_3D || m_unitTypes[unitNdx] == GL_TEXTURE_2D_ARRAY);

			float transData[4*4];

			for (int i = 0; i < 4*4; i++)
			{
				float sign = rnd.getBool() ? 1.0f : -1.0f;
				transData[i] = rnd.getFloat(0.7f, 1.4f) * sign;
			}

			Mat4 transformation(transData);

			if (m_unitTypes[unitNdx] == GL_TEXTURE_2D_ARRAY)
			{
				// Z direction: Translate by 0.5 and scale by layer amount.

				float numLayers = (float)num2dArrayLayers[tex2dArrayNdx];

				static const float zTranslationTransfData[4*4] =
				{
					1.0f, 0.0f, 0.0f, 0.0f,
					0.0f, 1.0f, 0.0f, 0.0f,
					0.0f, 0.0f, 1.0f, 0.5f,
					0.0f, 0.0f, 0.0f, 1.0f
				};

				float zScaleTransfData[4*4] =
				{
					1.0f,		0.0f,		0.0f,		0.0f,
					0.0f,		1.0f,		0.0f,		0.0f,
					0.0f,		0.0f,		numLayers,	0.0f,
					0.0f,		0.0f,		0.0f,		1.0f
				};

				transformation = transformation * Mat4(zScaleTransfData) * Mat4(zTranslationTransfData);

				tex2dArrayNdx++;
			}

			m_lodDerivateParts.push_back(calculateLodDerivateParts(transformation));
			m_transformations.push_back(Mat4(transformation));
		}
	}
}

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.uniformMatrix4fv(ctx.getUniformLocation(program, ("u_trans" + ndxStr).c_str()), 1, GL_FALSE, (GLfloat*)&m_transformations[ndx].getColumnMajorData()[0]);
		ctx.uniform4fv(ctx.getUniformLocation(program, ("u_texScale" + ndxStr).c_str()), 1, m_texScales[ndx].getPtr());
		ctx.uniform4fv(ctx.getUniformLocation(program, ("u_texBias" + ndxStr).c_str()), 1, m_texBiases[ndx].getPtr());
	}
}

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

	static const float shrinkScaleMat2dData[3*3] =
	{
		0.95f,	0.0f,	0.0f,
		0.0f,	0.95f,	0.0f,
		0.0f,	0.0f,	1.0f
	};
	static const float shrinkScaleMat3dData[3*3] =
	{
		0.95f,	0.0f,	0.0f,
		0.0f,	0.95f,	0.0f,
		0.0f,	0.0f,	0.95f
	};
	Mat4 shrinkScaleMat2d = matExtend3To4(Mat3(shrinkScaleMat2dData));
	Mat4 shrinkScaleMat3d = matExtend3To4(Mat3(shrinkScaleMat3dData));

	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] = (m_unitTypes[unitNdx] == GL_TEXTURE_3D ? shrinkScaleMat3d : shrinkScaleMat2d) * 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(),
			};

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

			// To 2D
			const tcu::Vec2 coords2D[4] =
			{
				coords3D[0].xy(),
				coords3D[1].xy(),
				coords3D[2].xy(),
				coords3D[3].xy(),
			};

			// Sample
			switch (m_unitTypes[unitNdx])
			{
				case GL_TEXTURE_2D:			m_uniforms[4*unitNdx].sampler.tex2D->sample4(texSamples, coords2D);			break;
				case GL_TEXTURE_CUBE_MAP:	m_uniforms[4*unitNdx].sampler.texCube->sample4(texSamples, coords3D);		break;
				case GL_TEXTURE_2D_ARRAY:	m_uniforms[4*unitNdx].sampler.tex2DArray->sample4(texSamples, coords3D);	break;
				case GL_TEXTURE_3D:			m_uniforms[4*unitNdx].sampler.tex3D->sample4(texSamples, coords3D);			break;
				default:
					DE_ASSERT(DE_FALSE);
			}

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

		// 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_ONLY_2D_ARRAY,
		CASE_ONLY_3D,
		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 internalFormat;
		GLenum wrapModeS;
		GLenum wrapModeT;
		GLenum wrapModeR;
		GLenum minFilter;
		GLenum magFilter;
	};

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

	void							upload2dTexture			(int texNdx, sglr::Context& context);
	void							uploadCubeTexture		(int texNdx, sglr::Context& context);
	void							upload2dArrayTexture	(int texNdx, sglr::Context& context);
	void							upload3dTexture			(int texNdx, sglr::Context& context);

	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<tcu::Texture2DArray*>	m_textures2dArray;
	vector<tcu::Texture3D*>			m_textures3d;
	vector<int>						m_unitTextures;	//!< Which texture is used in a particular unit.
	vector<int>						m_ndxTexType;	//!< Index of a texture in m_textures2d, m_texturesCube, m_textures2dArray or m_textures3d, 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();

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

	for (vector<tcu::Texture3D*>::iterator i = m_textures3d.begin(); i != m_textures3d.end(); i++)
		delete *i;
	m_textures3d.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_ndxTexType.reserve(m_numTextures);

		// Generate textures.

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

			TextureParameters	params;

			DE_STATIC_ASSERT(CASE_ONLY_2D == 0 && CASE_MIXED + 1 == CASE_LAST);

			int						texType			= m_caseType == CASE_MIXED ? rnd.getInt(0, (int)CASE_MIXED - 1) : (int)m_caseType;
			bool					is2dTex			= texType == 0;
			bool					isCubeTex		= texType == 1;
			bool					is2dArrayTex	= texType == 2;
			bool					is3dTex			= texType == 3;

			DE_ASSERT(is2dTex || isCubeTex || is2dArrayTex || is3dTex);

			GLenum					type			= is2dTex		? GL_TEXTURE_2D		: isCubeTex ? GL_TEXTURE_CUBE_MAP	: is2dArrayTex ? GL_TEXTURE_2D_ARRAY		: GL_TEXTURE_3D;
			const int				texWidth		= is2dTex		? TEXTURE_WIDTH_2D	: isCubeTex ? TEXTURE_WIDTH_CUBE	: is2dArrayTex ? TEXTURE_WIDTH_2D_ARRAY		: TEXTURE_WIDTH_3D;
			const int				texHeight		= is2dTex		? TEXTURE_HEIGHT_2D	: isCubeTex ? TEXTURE_HEIGHT_CUBE	: is2dArrayTex ? TEXTURE_HEIGHT_2D_ARRAY	: TEXTURE_HEIGHT_3D;

			const int				texDepth		= is3dTex ? TEXTURE_DEPTH_3D : 1;
			const int				texLayers		= is2dArrayTex ? TEXTURE_LAYERS_2D_ARRAY : 1;

			bool					mipmaps			= (deIsPowerOfTwo32(texWidth) && deIsPowerOfTwo32(texHeight) && deIsPowerOfTwo32(texDepth));
			int						numLevels		= mipmaps ? deLog2Floor32(de::max(de::max(texWidth, texHeight), texDepth))+1 : 1;

			params.internalFormat = s_testSizedInternalFormats[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_testSizedInternalFormats) - 1)];

			bool					isFilterable	= glu::isGLInternalColorFormatFilterable(params.internalFormat);

			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.wrapModeR = s_testWrapModes[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_testWrapModes) - 1)];

			params.magFilter = isFilterable ? s_testMagFilters[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_testMagFilters) - 1)] : GL_NEAREST;

			if (mipmaps)
				params.minFilter = isFilterable ?
					s_testMinFilters			[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_testMinFilters) - 1)] :
					s_testNearestMinFilters		[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_testNearestMinFilters) - 1)];
			else
				params.minFilter = isFilterable ?
					s_testNonMipmapMinFilters	[rnd.getInt(0, DE_LENGTH_OF_ARRAY(s_testNonMipmapMinFilters) - 1)] :
					GL_NEAREST;

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

			// Create new texture.

			tcu::TextureFormat texFormat = glu::mapGLInternalFormat((deUint32)params.internalFormat);

			if (is2dTex)
			{
				m_ndxTexType.push_back((int)m_textures2d.size()); // Remember the index this texture has in the 2d texture vector.
				m_textures2d.push_back(new tcu::Texture2D(texFormat, texWidth, texHeight));
			}
			else if (isCubeTex)
			{
				m_ndxTexType.push_back((int)m_texturesCube.size()); // Remember the index this texture has in the cube texture vector.
				DE_ASSERT(texWidth == texHeight);
				m_texturesCube.push_back(new tcu::TextureCube(texFormat, texWidth));
			}
			else if (is2dArrayTex)
			{
				m_ndxTexType.push_back((int)m_textures2dArray.size()); // Remember the index this texture has in the 2d array texture vector.
				m_textures2dArray.push_back(new tcu::Texture2DArray(texFormat, texWidth, texHeight, texLayers));
			}
			else
			{
				m_ndxTexType.push_back((int)m_textures3d.size()); // Remember the index this texture has in the 3d vector.
				m_textures3d.push_back(new tcu::Texture3D(texFormat, texWidth, texHeight, texDepth));
			}

			tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(texFormat);
			Vec4					cBias		= fmtInfo.valueMin;
			Vec4					cScale		= fmtInfo.valueMax-fmtInfo.valueMin;

			// Fill with grid texture.

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

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

				deUint32 colorA = alpha | rgb;
				deUint32 colorB = alpha | ((~rgb) & 0x00ffffff);

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

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

					tcu::PixelBufferAccess access = is2dTex			? m_textures2d.back()->getLevel(levelNdx)
												  : isCubeTex		? m_texturesCube.back()->getLevelFace(levelNdx, (tcu::CubeFace)face)
												  : is2dArrayTex	? m_textures2dArray.back()->getLevel(levelNdx)
												  :					  m_textures3d.back()->getLevel(levelNdx);

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

		// Generate information for shader.

		vector<GLenum>			unitTypes;
		vector<Vec4>			texScales;
		vector<Vec4>			texBiases;
		vector<glu::DataType>	samplerTypes;
		vector<int>				num2dArrayLayers;

		unitTypes.reserve(m_numUnits);
		texScales.reserve(m_numUnits);
		texBiases.reserve(m_numUnits);
		samplerTypes.reserve(m_numUnits);
		num2dArrayLayers.reserve(m_numUnits);

		for (int i = 0; i < m_numUnits; i++)
		{
			int						texNdx		= m_unitTextures[i];
			GLenum					type		= m_textureTypes[texNdx];
			tcu::TextureFormat		fmt			= glu::mapGLInternalFormat(m_textureParams[texNdx].internalFormat);
			tcu::TextureFormatInfo	fmtInfo		= tcu::getTextureFormatInfo(fmt);

			unitTypes.push_back(type);

			if (type == GL_TEXTURE_2D_ARRAY)
				num2dArrayLayers.push_back(m_textures2dArray[m_ndxTexType[texNdx]]->getNumLayers());

			texScales.push_back(fmtInfo.lookupScale);
			texBiases.push_back(fmtInfo.lookupBias);

			switch (type)
			{
				case GL_TEXTURE_2D:			samplerTypes.push_back(glu::getSampler2DType(fmt));			break;
				case GL_TEXTURE_CUBE_MAP:	samplerTypes.push_back(glu::getSamplerCubeType(fmt));		break;
				case GL_TEXTURE_2D_ARRAY:	samplerTypes.push_back(glu::getSampler2DArrayType(fmt));	break;
				case GL_TEXTURE_3D:			samplerTypes.push_back(glu::getSampler3DType(fmt));			break;
				default:
					DE_ASSERT(DE_FALSE);
			}
		}

		// Create shader.

		DE_ASSERT(m_shader == DE_NULL);
		m_shader = new MultiTexShader(rnd.getUint32(), m_numUnits, unitTypes, samplerTypes, texScales, texBiases, num2dArrayLayers);
	}
	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				gles3Frame			(viewportWidth, viewportHeight);
	tcu::Surface				refFrame			(viewportWidth, viewportHeight);

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

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

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

			switch (type)
			{
				case GL_TEXTURE_2D:			texSizes.push_back(IVec3(m_textures2d[texNdxInType]->getWidth(),		m_textures2d[texNdxInType]->getHeight(),		0));										break;
				case GL_TEXTURE_CUBE_MAP:	texSizes.push_back(IVec3(m_texturesCube[texNdxInType]->getSize(),		m_texturesCube[texNdxInType]->getSize(),		0));										break;
				case GL_TEXTURE_2D_ARRAY:	texSizes.push_back(IVec3(m_textures2dArray[texNdxInType]->getWidth(),	m_textures2dArray[texNdxInType]->getHeight(),	0));										break;
				case GL_TEXTURE_3D:			texSizes.push_back(IVec3(m_textures3d[texNdxInType]->getWidth(),		m_textures3d[texNdxInType]->getHeight(),		m_textures3d[texNdxInType]->getDepth()));	break;
				default:
					DE_ASSERT(DE_FALSE);
			}
		}

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

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

		render(context);

		context.readPixels(gles3Frame, 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, gles3Frame, 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::upload2dTexture (int texNdx, sglr::Context& context)
{
	int						ndx2d		= m_ndxTexType[texNdx];
	const tcu::Texture2D*	texture		= m_textures2d[ndx2d];
	glu::TransferFormat		formatGl	= glu::getTransferFormat(glu::mapGLInternalFormat(m_textureParams[texNdx].internalFormat));

	context.pixelStorei(GL_UNPACK_ALIGNMENT, 1);

	for (int levelNdx = 0; levelNdx < texture->getNumLevels(); levelNdx++)
	{
		if (texture->isLevelEmpty(levelNdx))
			continue;

		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].internalFormat, width, height, 0 /* border */, formatGl.format, formatGl.dataType, access.getDataPtr());
		GLU_EXPECT_NO_ERROR(context.getError(), "Set 2d texture image data");
	}
}

void TextureUnitCase::uploadCubeTexture (int texNdx, sglr::Context& context)
{
	int							ndxCube		= m_ndxTexType[texNdx];
	const tcu::TextureCube*		texture		= m_texturesCube[ndxCube];
	glu::TransferFormat			formatGl	= glu::getTransferFormat(glu::mapGLInternalFormat(m_textureParams[texNdx].internalFormat));

	context.pixelStorei(GL_UNPACK_ALIGNMENT, 1);

	for (int face = 0; face < (int)tcu::CUBEFACE_LAST; face++)
	{
		for (int levelNdx = 0; levelNdx < texture->getNumLevels(); levelNdx++)
		{
			if (texture->isLevelEmpty((tcu::CubeFace)face, levelNdx))
				continue;

			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].internalFormat, width, height, 0 /* border */, formatGl.format, formatGl.dataType, access.getDataPtr());
			GLU_EXPECT_NO_ERROR(context.getError(), "Set cube map image data");
		}
	}
}

void TextureUnitCase::upload2dArrayTexture (int texNdx, sglr::Context& context)
{
	int							ndx2dArray	= m_ndxTexType[texNdx];
	const tcu::Texture2DArray*	texture		= m_textures2dArray[ndx2dArray];
	glu::TransferFormat			formatGl	= glu::getTransferFormat(glu::mapGLInternalFormat(m_textureParams[texNdx].internalFormat));

	context.pixelStorei(GL_UNPACK_ALIGNMENT, 1);

	for (int levelNdx = 0; levelNdx < texture->getNumLevels(); levelNdx++)
	{
		if (texture->isLevelEmpty(levelNdx))
			continue;

		tcu::ConstPixelBufferAccess	access	= texture->getLevel(levelNdx);
		int							width	= access.getWidth();
		int							height	= access.getHeight();
		int							layers	= access.getDepth();

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

		context.texImage3D(GL_TEXTURE_2D_ARRAY, levelNdx, m_textureParams[texNdx].internalFormat, width, height, layers, 0 /* border */, formatGl.format, formatGl.dataType, access.getDataPtr());
		GLU_EXPECT_NO_ERROR(context.getError(), "Set 2d array texture image data");
	}
}

void TextureUnitCase::upload3dTexture (int texNdx, sglr::Context& context)
{
	int							ndx3d		= m_ndxTexType[texNdx];
	const tcu::Texture3D*		texture		= m_textures3d[ndx3d];
	glu::TransferFormat			formatGl	= glu::getTransferFormat(glu::mapGLInternalFormat(m_textureParams[texNdx].internalFormat));

	context.pixelStorei(GL_UNPACK_ALIGNMENT, 1);

	for (int levelNdx = 0; levelNdx < texture->getNumLevels(); levelNdx++)
	{
		if (texture->isLevelEmpty(levelNdx))
			continue;

		tcu::ConstPixelBufferAccess	access	= texture->getLevel(levelNdx);
		int							width	= access.getWidth();
		int							height	= access.getHeight();
		int							depth	= access.getDepth();

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

		context.texImage3D(GL_TEXTURE_3D, levelNdx, m_textureParams[texNdx].internalFormat, width, height, depth, 0 /* border */, formatGl.format, formatGl.dataType, access.getDataPtr());
		GLU_EXPECT_NO_ERROR(context.getError(), "Set 3d texture image data");
	}
}

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]);
	GLU_EXPECT_NO_ERROR(context.getError(), "Generate textures");

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

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

		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);
			if (m_textureTypes[texNdx] == GL_TEXTURE_3D)
				context.texParameteri(m_textureTypes[texNdx], GL_TEXTURE_WRAP_R, m_textureParams[texNdx].wrapModeR);
			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);
			GLU_EXPECT_NO_ERROR(context.getError(), "Set texture parameters");

			switch (m_textureTypes[texNdx])
			{
				case GL_TEXTURE_2D:			upload2dTexture(texNdx, context);		break;
				case GL_TEXTURE_CUBE_MAP:	uploadCubeTexture(texNdx, context);		break;
				case GL_TEXTURE_2D_ARRAY:	upload2dArrayTexture(texNdx, context);	break;
				case GL_TEXTURE_3D:			upload3dTexture(texNdx, context);		break;
				default:
					DE_ASSERT(DE_FALSE);
			}

			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_ONLY_2D_ARRAY	? "only_2d_array"
										  : (TextureUnitCase::CaseType)caseType == TextureUnitCase::CASE_ONLY_3D		? "only_3d"
										  : (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, deUint32Hash((deUint32)testNdx)));
		}
	}
}

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