/*-------------------------------------------------------------------------
 * 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 specification tests.
 *
 * \todo [pyry] Following tests are missing:
 *  - Specify mipmap incomplete texture, use without mipmaps, re-specify
 *    as complete and render.
 *  - Randomly re-specify levels to eventually reach mipmap-complete texture.
 *//*--------------------------------------------------------------------*/

#include "es2fTextureSpecificationTests.hpp"
#include "tcuTestLog.hpp"
#include "tcuImageCompare.hpp"
#include "gluTextureUtil.hpp"
#include "sglrContextUtil.hpp"
#include "sglrContextWrapper.hpp"
#include "sglrGLContext.hpp"
#include "sglrReferenceContext.hpp"
#include "glsTextureTestUtil.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuFormatUtil.hpp"
#include "tcuVectorUtil.hpp"
#include "deRandom.hpp"
#include "deStringUtil.hpp"

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

namespace deqp
{
namespace gles2
{
namespace Functional
{

using std::string;
using std::vector;
using std::pair;
using tcu::TestLog;
using tcu::Vec4;
using tcu::IVec4;
using tcu::UVec4;

tcu::TextureFormat mapGLUnsizedInternalFormat (deUint32 internalFormat)
{
	using tcu::TextureFormat;
	switch (internalFormat)
	{
		case GL_ALPHA:				return TextureFormat(TextureFormat::A,		TextureFormat::UNORM_INT8);
		case GL_LUMINANCE:			return TextureFormat(TextureFormat::L,		TextureFormat::UNORM_INT8);
		case GL_LUMINANCE_ALPHA:	return TextureFormat(TextureFormat::LA,		TextureFormat::UNORM_INT8);
		case GL_RGB:				return TextureFormat(TextureFormat::RGB,	TextureFormat::UNORM_INT8);
		case GL_RGBA:				return TextureFormat(TextureFormat::RGBA,	TextureFormat::UNORM_INT8);
		default:
			throw tcu::InternalError(string("Can't map GL unsized internal format (") + tcu::toHex(internalFormat).toString() + ") to texture format");
	}
}

template <int Size>
static tcu::Vector<float, Size> randomVector (de::Random& rnd, const tcu::Vector<float, Size>& minVal = tcu::Vector<float, Size>(0.0f), const tcu::Vector<float, Size>& maxVal = tcu::Vector<float, Size>(1.0f))
{
	tcu::Vector<float, Size> res;
	for (int ndx = 0; ndx < Size; ndx++)
		res[ndx] = rnd.getFloat(minVal[ndx], maxVal[ndx]);
	return res;
}

static tcu::IVec4 getPixelFormatCompareDepth (const tcu::PixelFormat& pixelFormat, tcu::TextureFormat textureFormat)
{
	switch (textureFormat.order)
	{
		case tcu::TextureFormat::L:
		case tcu::TextureFormat::LA:
			return tcu::IVec4(pixelFormat.redBits, pixelFormat.redBits, pixelFormat.redBits, pixelFormat.alphaBits);
		default:
			return tcu::IVec4(pixelFormat.redBits, pixelFormat.greenBits, pixelFormat.blueBits, pixelFormat.alphaBits);
	}
}

static tcu::UVec4 computeCompareThreshold (const tcu::PixelFormat& pixelFormat, tcu::TextureFormat textureFormat)
{
	const IVec4		texFormatBits		= tcu::getTextureFormatBitDepth(textureFormat);
	const IVec4		pixelFormatBits		= getPixelFormatCompareDepth(pixelFormat, textureFormat);
	const IVec4		accurateFmtBits		= min(pixelFormatBits, texFormatBits);
	const IVec4		compareBits			= select(accurateFmtBits, IVec4(8), greaterThan(accurateFmtBits, IVec4(0))) - 1;

	return (IVec4(1) << (8-compareBits)).asUint();
}

class GradientShader : public sglr::ShaderProgram
{
public:
	GradientShader (void)
		: ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
					<< sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
					<< sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT)
					<< sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
					<< sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
					<< sglr::pdec::VertexSource("attribute highp vec4 a_position;\n"
												"attribute mediump vec2 a_coord;\n"
												"varying mediump vec2 v_coord;\n"
												"void main (void)\n"
												"{\n"
												"	gl_Position = a_position;\n"
												"	v_coord = a_coord;\n"
												"}\n")
					<< sglr::pdec::FragmentSource("varying mediump vec2 v_coord;\n"
												  "void main (void)\n"
												  "{\n"
												  "	mediump float x = v_coord.x;\n"
												  "	mediump float y = v_coord.y;\n"
												  "	mediump float f0 = (x + y) * 0.5;\n"
												  "	mediump float f1 = 0.5 + (x - y) * 0.5;\n"
												  "	gl_FragColor = vec4(f0, f1, 1.0-f0, 1.0-f1);\n"
												  "}\n"))
	{
	}

	void 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 shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
	{
		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
		for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
		{
			const tcu::Vec4		coord	= rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx);
			const float			x		= coord.x();
			const float			y		= coord.y();
			const float			f0		= (x + y) * 0.5f;
			const float			f1		= 0.5f + (x - y) * 0.5f;

			rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, tcu::Vec4(f0, f1, 1.0f-f0, 1.0f-f1));
		}
	}
};

class Tex2DShader : public sglr::ShaderProgram
{
public:
	Tex2DShader (void)
		: ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
					<< sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
					<< sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT)
					<< sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
					<< sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
					<< sglr::pdec::Uniform("u_sampler0", glu::TYPE_SAMPLER_2D)
					<< sglr::pdec::VertexSource("attribute highp vec4 a_position;\n"
												"attribute mediump vec2 a_coord;\n"
												"varying mediump vec2 v_coord;\n"
												"void main (void)\n"
												"{\n"
												"	gl_Position = a_position;\n"
												"	v_coord = a_coord;\n"
												"}\n")
					<< sglr::pdec::FragmentSource("uniform sampler2D u_sampler0;\n"
												  "varying mediump vec2 v_coord;\n"
												  "void main (void)\n"
												  "{\n"
												  "	gl_FragColor = texture2D(u_sampler0, v_coord);\n"
												  "}\n"))
	{
	}

	void setUniforms (sglr::Context& ctx, deUint32 program) const
	{
		ctx.useProgram(program);
		ctx.uniform1i(ctx.getUniformLocation(program, "u_sampler0"), 0);
	}

	void 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 shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
	{
		tcu::Vec2 texCoords[4];
		tcu::Vec4 colors[4];

		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
		{
			// setup tex coords
			for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
			{
				const tcu::Vec4	coord = rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx);
				texCoords[fragNdx] = tcu::Vec2(coord.x(), coord.y());
			}

			// Sample
			m_uniforms[0].sampler.tex2D->sample4(colors, texCoords);

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

static const char* s_cubeSwizzles[] =
{
	"vec3(-1, -y, +x)",
	"vec3(+1, -y, -x)",
	"vec3(+x, -1, -y)",
	"vec3(+x, +1, +y)",
	"vec3(-x, -y, -1)",
	"vec3(+x, -y, +1)"
};

class TexCubeShader : public sglr::ShaderProgram
{
public:
	TexCubeShader (tcu::CubeFace face)
		: ShaderProgram(sglr::pdec::ShaderProgramDeclaration()
					<< sglr::pdec::VertexAttribute("a_position", rr::GENERICVECTYPE_FLOAT)
					<< sglr::pdec::VertexAttribute("a_coord", rr::GENERICVECTYPE_FLOAT)
					<< sglr::pdec::VertexToFragmentVarying(rr::GENERICVECTYPE_FLOAT)
					<< sglr::pdec::FragmentOutput(rr::GENERICVECTYPE_FLOAT)
					<< sglr::pdec::Uniform("u_sampler0", glu::TYPE_SAMPLER_CUBE)
					<< sglr::pdec::VertexSource("attribute highp vec4 a_position;\n"
												"attribute mediump vec2 a_coord;\n"
												"varying mediump vec2 v_coord;\n"
												"void main (void)\n"
												"{\n"
												"	gl_Position = a_position;\n"
												"	v_coord = a_coord;\n"
												"}\n")
					<< sglr::pdec::FragmentSource(string("") +
												  "uniform samplerCube u_sampler0;\n"
												  "varying mediump vec2 v_coord;\n"
												  "void main (void)\n"
												  "{\n"
												  "	mediump float x = v_coord.x*2.0 - 1.0;\n"
												  "	mediump float y = v_coord.y*2.0 - 1.0;\n"
												  "	gl_FragColor = textureCube(u_sampler0, " + s_cubeSwizzles[face] + ");\n"
												  "}\n"))
		, m_face(face)
	{
	}

	void setUniforms (sglr::Context& ctx, deUint32 program) const
	{
		ctx.useProgram(program);
		ctx.uniform1i(ctx.getUniformLocation(program, "u_sampler0"), 0);
	}

	void 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 shadeFragments (rr::FragmentPacket* packets, const int numPackets, const rr::FragmentShadingContext& context) const
	{
		tcu::Vec3 texCoords[4];
		tcu::Vec4 colors[4];

		for (int packetNdx = 0; packetNdx < numPackets; ++packetNdx)
		{
			// setup tex coords
			for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
			{
				const tcu::Vec4	coord	= rr::readTriangleVarying<float>(packets[packetNdx], context, 0, fragNdx);
				const float		x		= coord.x()*2.0f - 1.0f;
				const float		y		= coord.y()*2.0f - 1.0f;

				// Swizzle tex coords
				switch (m_face)
				{
					case tcu::CUBEFACE_NEGATIVE_X:	texCoords[fragNdx] = tcu::Vec3(-1.0f,    -y,    +x);		break;
					case tcu::CUBEFACE_POSITIVE_X:	texCoords[fragNdx] = tcu::Vec3(+1.0f,    -y,    -x);		break;
					case tcu::CUBEFACE_NEGATIVE_Y:	texCoords[fragNdx] = tcu::Vec3(   +x, -1.0f,    -y);		break;
					case tcu::CUBEFACE_POSITIVE_Y:	texCoords[fragNdx] = tcu::Vec3(   +x, +1.0f,    +y);		break;
					case tcu::CUBEFACE_NEGATIVE_Z:	texCoords[fragNdx] = tcu::Vec3(   -x,    -y, -1.0f);		break;
					case tcu::CUBEFACE_POSITIVE_Z:	texCoords[fragNdx] = tcu::Vec3(   +x,    -y, +1.0f);		break;
					default:
						DE_ASSERT(false);
				}
			}

			// Sample
			m_uniforms[0].sampler.texCube->sample4(colors, texCoords);

			// Write out
			for (int fragNdx = 0; fragNdx < 4; ++fragNdx)
				rr::writeFragmentOutput(context, packetNdx, fragNdx, 0, colors[fragNdx]);
		}
	}
private:
	tcu::CubeFace m_face;
};

enum TextureType
{
	TEXTURETYPE_2D = 0,
	TEXTURETYPE_CUBE,

	TEXTURETYPE_LAST
};

enum Flags
{
	MIPMAPS		= (1<<0)
};

static const deUint32 s_cubeMapFaces[] =
{
	GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
	GL_TEXTURE_CUBE_MAP_POSITIVE_X,
	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
	GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
	GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
};

class TextureSpecCase : public TestCase, public sglr::ContextWrapper
{
public:
								TextureSpecCase		(Context& context, const char* name, const char* desc, const TextureType type, const tcu::TextureFormat format, const deUint32 flags, int width, int height);
								~TextureSpecCase	(void);

	IterateResult				iterate				(void);

protected:
	virtual void				createTexture		(void) = DE_NULL;

	const TextureType			m_texType;
	const tcu::TextureFormat	m_texFormat;
	const deUint32				m_flags;
	const int					m_width;
	const int					m_height;

	bool m_half_float_oes;

private:
								TextureSpecCase		(const TextureSpecCase& other);
	TextureSpecCase&			operator=			(const TextureSpecCase& other);

	void						verifyTex2D			(sglr::GLContext& gles2Context, sglr::ReferenceContext& refContext);
	void						verifyTexCube		(sglr::GLContext& gles2Context, sglr::ReferenceContext& refContext);

	void						renderTex2D			(tcu::Surface& dst, int width, int height);
	void						renderTexCube		(tcu::Surface& dst, int width, int height, tcu::CubeFace face);

	void						readPixels			(tcu::Surface& dst, int x, int y, int width, int height);

	// \todo [2012-03-27 pyry] Renderer should be extended to allow custom attributes, that would clean up this cubemap mess.
	Tex2DShader					m_tex2DShader;
	TexCubeShader				m_texCubeNegXShader;
	TexCubeShader				m_texCubePosXShader;
	TexCubeShader				m_texCubeNegYShader;
	TexCubeShader				m_texCubePosYShader;
	TexCubeShader				m_texCubeNegZShader;
	TexCubeShader				m_texCubePosZShader;
};

TextureSpecCase::TextureSpecCase (Context& context, const char* name, const char* desc, const TextureType type, const tcu::TextureFormat format, const deUint32 flags, int width, int height)
	: TestCase				(context, name, desc)
	, m_texType				(type)
	, m_texFormat			(format)
	, m_flags				(flags)
	, m_width				(width)
	, m_height				(height)
	, m_texCubeNegXShader	(tcu::CUBEFACE_NEGATIVE_X)
	, m_texCubePosXShader	(tcu::CUBEFACE_POSITIVE_X)
	, m_texCubeNegYShader	(tcu::CUBEFACE_NEGATIVE_Y)
	, m_texCubePosYShader	(tcu::CUBEFACE_POSITIVE_Y)
	, m_texCubeNegZShader	(tcu::CUBEFACE_NEGATIVE_Z)
	, m_texCubePosZShader	(tcu::CUBEFACE_POSITIVE_Z)
{
	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
	m_half_float_oes = glu::hasExtension(gl, glu::ApiType::es(2, 0), "GL_OES_texture_half_float");
}

TextureSpecCase::~TextureSpecCase (void)
{
}

TextureSpecCase::IterateResult TextureSpecCase::iterate (void)
{
	glu::RenderContext&			renderCtx				= TestCase::m_context.getRenderContext();
	const tcu::RenderTarget&	renderTarget			= renderCtx.getRenderTarget();
	tcu::TestLog&				log						= m_testCtx.getLog();

	DE_ASSERT(m_width <= 256 && m_height <= 256);
	if (renderTarget.getWidth() < m_width || renderTarget.getHeight() < m_height)
		throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);

	// Context size, and viewport for GLES2
	de::Random		rnd			(deStringHash(getName()));
	int				width		= deMin32(renderTarget.getWidth(),	256);
	int				height		= deMin32(renderTarget.getHeight(),	256);
	int				x			= rnd.getInt(0, renderTarget.getWidth()		- width);
	int				y			= rnd.getInt(0, renderTarget.getHeight()	- height);

	// Contexts.
	sglr::GLContext					gles2Context	(renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(x, y, width, height));
	sglr::ReferenceContextBuffers	refBuffers		(tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), 0 /* depth */, 0 /* stencil */, width, height);
	sglr::ReferenceContext			refContext		(sglr::ReferenceContextLimits(renderCtx), refBuffers.getColorbuffer(), refBuffers.getDepthbuffer(), refBuffers.getStencilbuffer());

	// Clear color buffer.
	for (int ndx = 0; ndx < 2; ndx++)
	{
		setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles2Context);
		glClearColor(0.125f, 0.25f, 0.5f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
	}

	// Construct texture using both GLES2 and reference contexts.
	for (int ndx = 0; ndx < 2; ndx++)
	{
		setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles2Context);
		createTexture();
		TCU_CHECK(glGetError() == GL_NO_ERROR);
	}

	// Setup texture filtering state.
	for (int ndx = 0; ndx < 2; ndx++)
	{
		setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles2Context);

		deUint32 texTarget = m_texType == TEXTURETYPE_2D ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP;
		glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER,	(m_flags & MIPMAPS) ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST);
		glTexParameteri(texTarget, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
		glTexParameteri(texTarget, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
		glTexParameteri(texTarget, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
	}

	// Initialize case result to pass.
	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");

	// Disable logging.
	gles2Context.enableLogging(0);

	// Verify results.
	switch (m_texType)
	{
		case TEXTURETYPE_2D:	verifyTex2D		(gles2Context, refContext);	break;
		case TEXTURETYPE_CUBE:	verifyTexCube	(gles2Context, refContext);	break;
		default:
			DE_ASSERT(false);
	}

	return STOP;
}

void TextureSpecCase::verifyTex2D (sglr::GLContext& gles2Context, sglr::ReferenceContext& refContext)
{
	int numLevels = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;

	DE_ASSERT(m_texType == TEXTURETYPE_2D);

	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
	{
		int				levelW		= de::max(1, m_width >> levelNdx);
		int				levelH		= de::max(1, m_height >> levelNdx);
		tcu::Surface	reference;
		tcu::Surface	result;

		if (levelW <= 2 || levelH <= 2)
			continue; // Don't bother checking.

		// Render with GLES2
		setContext(&gles2Context);
		renderTex2D(result, levelW, levelH);

		// Render reference.
		setContext(&refContext);
		renderTex2D(reference, levelW, levelH);

		{
			tcu::UVec4	threshold	= computeCompareThreshold(m_context.getRenderTarget().getPixelFormat(), m_texFormat);
			bool		isOk		= tcu::intThresholdCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference.getAccess(), result.getAccess(), threshold,
															   levelNdx == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);

			if (!isOk)
			{
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
				break;
			}
		}
	}
}

void TextureSpecCase::verifyTexCube (sglr::GLContext& gles2Context, sglr::ReferenceContext& refContext)
{
	int numLevels = (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;

	DE_ASSERT(m_texType == TEXTURETYPE_CUBE);

	for (int levelNdx = 0; levelNdx < numLevels; levelNdx++)
	{
		int		levelW	= de::max(1, m_width >> levelNdx);
		int		levelH	= de::max(1, m_height >> levelNdx);
		bool	isOk	= true;

		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
		{
			tcu::Surface	reference;
			tcu::Surface	result;

			if (levelW <= 2 || levelH <= 2)
				continue; // Don't bother checking.

			// Render with GLES2
			setContext(&gles2Context);
			renderTexCube(result, levelW, levelH, (tcu::CubeFace)face);

			// Render reference.
			setContext(&refContext);
			renderTexCube(reference, levelW, levelH, (tcu::CubeFace)face);

			const float	threshold	= 0.02f;
			isOk = tcu::fuzzyCompare(m_testCtx.getLog(), "Result", (string("Image comparison result: ") + de::toString((tcu::CubeFace)face)).c_str(), reference, result, threshold,
									 levelNdx == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);

			if (!isOk)
			{
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
				break;
			}
		}

		if (!isOk)
			break;
	}
}

void TextureSpecCase::renderTex2D (tcu::Surface& dst, int width, int height)
{
	int			targetW		= getWidth();
	int			targetH		= getHeight();

	float		w			= (float)width	/ (float)targetW;
	float		h			= (float)height	/ (float)targetH;

	deUint32	shaderID	= getCurrentContext()->createProgram(&m_tex2DShader);

	m_tex2DShader.setUniforms(*getCurrentContext(), shaderID);
	sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(-1.0f + w*2.0f, -1.0f + h*2.0f, 0.0f));

	// Read pixels back.
	readPixels(dst, 0, 0, width, height);
}

void TextureSpecCase::renderTexCube (tcu::Surface& dst, int width, int height, tcu::CubeFace face)
{
	int		targetW		= getWidth();
	int		targetH		= getHeight();

	float	w			= (float)width	/ (float)targetW;
	float	h			= (float)height	/ (float)targetH;

	TexCubeShader* shaders[] =
	{
		&m_texCubeNegXShader,
		&m_texCubePosXShader,
		&m_texCubeNegYShader,
		&m_texCubePosYShader,
		&m_texCubeNegZShader,
		&m_texCubePosZShader
	};

	deUint32	shaderID	= getCurrentContext()->createProgram(shaders[face]);

	shaders[face]->setUniforms(*getCurrentContext(), shaderID);
	sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(-1.0f + w*2.0f, -1.0f + h*2.0f, 0.0f));

	// Read pixels back.
	readPixels(dst, 0, 0, width, height);
}

void TextureSpecCase::readPixels (tcu::Surface& dst, int x, int y, int width, int height)
{
	dst.setSize(width, height);
	glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, dst.getAccess().getDataPtr());
}

// Basic TexImage2D() with 2D texture usage
class BasicTexImage2DCase : public TextureSpecCase
{
public:
	BasicTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
		: TextureSpecCase	(context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
		, m_format			(format)
		, m_dataType		(dataType)
	{
	}

protected:
	void createTexture (void)
	{
		tcu::TextureFormat	fmt			= m_texFormat;
		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
		deUint32			tex			= 0;
		tcu::TextureLevel	levelData	(fmt);
		de::Random			rnd			(deStringHash(getName()));

		if (m_dataType == GL_HALF_FLOAT_OES && !m_half_float_oes)
			throw tcu::NotSupportedError("GL_OES_texture_half_float is not supported", "", __FILE__, __LINE__);

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_2D, tex);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_width >> ndx);
			int		levelH		= de::max(1, m_height >> ndx);
			Vec4	gMin		= randomVector<4>(rnd);
			Vec4	gMax		= randomVector<4>(rnd);

			levelData.setSize(levelW, levelH);
			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);

			glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
		}
	}

	deUint32	m_format;
	deUint32	m_dataType;
};

// Basic TexImage2D() with cubemap usage
class BasicTexImageCubeCase : public TextureSpecCase
{
public:
	BasicTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
		: TextureSpecCase	(context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
		, m_format			(format)
		, m_dataType		(dataType)
	{
	}

protected:
	void createTexture (void)
	{
		tcu::TextureFormat	fmt			= m_texFormat;
		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
		deUint32			tex			= 0;
		tcu::TextureLevel	levelData	(fmt);
		de::Random			rnd			(deStringHash(getName()));

		DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.

		if (m_dataType == GL_HALF_FLOAT_OES && !m_half_float_oes)
			throw tcu::NotSupportedError("GL_OES_texture_half_float is not supported", "", __FILE__, __LINE__);

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_width >> ndx);
			int		levelH		= de::max(1, m_height >> ndx);

			levelData.setSize(levelW, levelH);

			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
			{
				Vec4 gMin = randomVector<4>(rnd);
				Vec4 gMax = randomVector<4>(rnd);

				tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);

				glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
			}
		}
	}

	deUint32	m_format;
	deUint32	m_dataType;
};

// Randomized 2D texture specification using TexImage2D
class RandomOrderTexImage2DCase : public TextureSpecCase
{
public:
	RandomOrderTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
		: TextureSpecCase	(context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
		, m_format			(format)
		, m_dataType		(dataType)
	{
	}

protected:
	void createTexture (void)
	{
		tcu::TextureFormat	fmt			= m_texFormat;
		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
		deUint32			tex			= 0;
		tcu::TextureLevel	levelData	(fmt);
		de::Random			rnd			(deStringHash(getName()));

		if (m_dataType == GL_HALF_FLOAT_OES && !m_half_float_oes)
			throw tcu::NotSupportedError("GL_OES_texture_half_float is not supported", "", __FILE__, __LINE__);

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_2D, tex);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

		vector<int>			levels		(numLevels);

		for (int i = 0; i < numLevels; i++)
			levels[i] = i;
		rnd.shuffle(levels.begin(), levels.end());

		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelNdx	= levels[ndx];
			int		levelW		= de::max(1, m_width	>> levelNdx);
			int		levelH		= de::max(1, m_height	>> levelNdx);
			Vec4	gMin		= randomVector<4>(rnd);
			Vec4	gMax		= randomVector<4>(rnd);

			levelData.setSize(levelW, levelH);
			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);

			glTexImage2D(GL_TEXTURE_2D, levelNdx, m_format, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
		}
	}

	deUint32	m_format;
	deUint32	m_dataType;
};

// Randomized cubemap texture specification using TexImage2D
class RandomOrderTexImageCubeCase : public TextureSpecCase
{
public:
	RandomOrderTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
		: TextureSpecCase	(context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
		, m_format			(format)
		, m_dataType		(dataType)
	{
	}

protected:
	void createTexture (void)
	{
		tcu::TextureFormat	fmt			= m_texFormat;
		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
		deUint32			tex			= 0;
		tcu::TextureLevel	levelData	(fmt);
		de::Random			rnd			(deStringHash(getName()));

		DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.

		if (m_dataType == GL_HALF_FLOAT_OES && !m_half_float_oes)
			throw tcu::NotSupportedError("GL_OES_texture_half_float is not supported", "", __FILE__, __LINE__);

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

		// Level-face pairs.
		vector<pair<int, tcu::CubeFace> >	images	(numLevels*6);

		for (int ndx = 0; ndx < numLevels; ndx++)
			for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
				images[ndx*6 + face] = std::make_pair(ndx, (tcu::CubeFace)face);

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

		for (int ndx = 0; ndx < (int)images.size(); ndx++)
		{
			int				levelNdx	= images[ndx].first;
			tcu::CubeFace	face		= images[ndx].second;
			int				levelW		= de::max(1, m_width >> levelNdx);
			int				levelH		= de::max(1, m_height >> levelNdx);
			Vec4			gMin		= randomVector<4>(rnd);
			Vec4			gMax		= randomVector<4>(rnd);

			levelData.setSize(levelW, levelH);
			tcu::fillWithComponentGradients(levelData.getAccess(), gMin, gMax);

			glTexImage2D(s_cubeMapFaces[face], levelNdx, m_format, levelW, levelH, 0, m_format, m_dataType, levelData.getAccess().getDataPtr());
		}
	}

	deUint32	m_format;
	deUint32	m_dataType;
};

static inline int getRowPitch (const tcu::TextureFormat& transferFmt, int rowLen, int alignment)
{
	int basePitch = transferFmt.getPixelSize()*rowLen;
	return alignment*(basePitch/alignment + ((basePitch % alignment) ? 1 : 0));
}

// TexImage2D() unpack alignment case.
class TexImage2DAlignCase : public TextureSpecCase
{
public:
	TexImage2DAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height, int alignment)
		: TextureSpecCase	(context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
		, m_format			(format)
		, m_dataType		(dataType)
		, m_alignment		(alignment)
	{
	}

protected:
	void createTexture (void)
	{
		tcu::TextureFormat	fmt			= m_texFormat;
		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
		deUint32			tex			= 0;
		vector<deUint8>		data;

		if (m_dataType == GL_HALF_FLOAT_OES && !m_half_float_oes)
			throw tcu::NotSupportedError("GL_OES_texture_half_float is not supported", "", __FILE__, __LINE__);

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_2D, tex);
		glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);

		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_width >> ndx);
			int		levelH		= de::max(1, m_height >> ndx);
			Vec4	colorA		(1.0f, 0.0f, 0.0f, 1.0f);
			Vec4	colorB		(0.0f, 1.0f, 0.0f, 1.0f);
			int		rowPitch	= getRowPitch(fmt, levelW, m_alignment);
			int		cellSize	= de::max(1, de::min(levelW >> 2, levelH >> 2));

			data.resize(rowPitch*levelH);
			tcu::fillWithGrid(tcu::PixelBufferAccess(fmt, levelW, levelH, 1, rowPitch, 0, &data[0]), cellSize, colorA, colorB);

			glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, &data[0]);
		}
	}

	deUint32	m_format;
	deUint32	m_dataType;
	int			m_alignment;
};

// TexImage2D() unpack alignment case.
class TexImageCubeAlignCase : public TextureSpecCase
{
public:
	TexImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height, int alignment)
		: TextureSpecCase	(context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
		, m_format			(format)
		, m_dataType		(dataType)
		, m_alignment		(alignment)
	{
	}

protected:
	void createTexture (void)
	{
		tcu::TextureFormat	fmt			= m_texFormat;
		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
		deUint32			tex			= 0;
		vector<deUint8>		data;

		DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.

		if (m_dataType == GL_HALF_FLOAT_OES && !m_half_float_oes)
			throw tcu::NotSupportedError("GL_OES_texture_half_float is not supported", "", __FILE__, __LINE__);

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
		glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);

		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_width >> ndx);
			int		levelH		= de::max(1, m_height >> ndx);
			int		rowPitch	= getRowPitch(fmt, levelW, m_alignment);
			Vec4	colorA		(1.0f, 0.0f, 0.0f, 1.0f);
			Vec4	colorB		(0.0f, 1.0f, 0.0f, 1.0f);
			int		cellSize	= de::max(1, de::min(levelW >> 2, levelH >> 2));

			data.resize(rowPitch*levelH);
			tcu::fillWithGrid(tcu::PixelBufferAccess(fmt, levelW, levelH, 1, rowPitch, 0, &data[0]), cellSize, colorA, colorB);

			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
				glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelW, levelH, 0, m_format, m_dataType, &data[0]);
		}
	}

	deUint32	m_format;
	deUint32	m_dataType;
	int			m_alignment;
};

// Basic TexSubImage2D() with 2D texture usage
class BasicTexSubImage2DCase : public TextureSpecCase
{
public:
	BasicTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
		: TextureSpecCase	(context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
		, m_format			(format)
		, m_dataType		(dataType)
	{
	}

protected:
	void createTexture (void)
	{
		tcu::TextureFormat	fmt			= m_texFormat;
		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
		deUint32			tex			= 0;
		tcu::TextureLevel	data		(fmt);
		de::Random			rnd			(deStringHash(getName()));

		if (m_dataType == GL_HALF_FLOAT_OES && !m_half_float_oes)
			throw tcu::NotSupportedError("GL_OES_texture_half_float is not supported", "", __FILE__, __LINE__);

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_2D, tex);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

		// First specify full texture.
		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_width >> ndx);
			int		levelH		= de::max(1, m_height >> ndx);
			Vec4	gMin		= randomVector<4>(rnd);
			Vec4	gMax		= randomVector<4>(rnd);

			data.setSize(levelW, levelH);
			tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);

			glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
		}

		// Re-specify parts of each level.
		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_width >> ndx);
			int		levelH		= de::max(1, m_height >> ndx);

			int		w			= rnd.getInt(1, levelW);
			int		h			= rnd.getInt(1, levelH);
			int		x			= rnd.getInt(0, levelW-w);
			int		y			= rnd.getInt(0, levelH-h);

			Vec4	colorA		= randomVector<4>(rnd);
			Vec4	colorB		= randomVector<4>(rnd);
			int		cellSize	= rnd.getInt(2, 16);

			data.setSize(w, h);
			tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);

			glTexSubImage2D(GL_TEXTURE_2D, ndx, x, y, w, h, m_format, m_dataType, data.getAccess().getDataPtr());
		}
	}

	deUint32	m_format;
	deUint32	m_dataType;
};

// Basic TexSubImage2D() with cubemap usage
class BasicTexSubImageCubeCase : public TextureSpecCase
{
public:
	BasicTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
		: TextureSpecCase	(context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
		, m_format			(format)
		, m_dataType		(dataType)
	{
	}

protected:
	void createTexture (void)
	{
		tcu::TextureFormat	fmt			= m_texFormat;
		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
		deUint32			tex			= 0;
		tcu::TextureLevel	data		(fmt);
		de::Random			rnd			(deStringHash(getName()));

		DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.

		if (m_dataType == GL_HALF_FLOAT_OES && !m_half_float_oes)
			throw tcu::NotSupportedError("GL_OES_texture_half_float is not supported", "", __FILE__, __LINE__);

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_width >> ndx);
			int		levelH		= de::max(1, m_height >> ndx);

			data.setSize(levelW, levelH);

			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
			{
				Vec4 gMin = randomVector<4>(rnd);
				Vec4 gMax = randomVector<4>(rnd);

				tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);

				glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
			}
		}

		// Re-specify parts of each face and level.
		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_width >> ndx);
			int		levelH		= de::max(1, m_height >> ndx);

			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
			{
				int		w			= rnd.getInt(1, levelW);
				int		h			= rnd.getInt(1, levelH);
				int		x			= rnd.getInt(0, levelW-w);
				int		y			= rnd.getInt(0, levelH-h);

				Vec4	colorA		= randomVector<4>(rnd);
				Vec4	colorB		= randomVector<4>(rnd);
				int		cellSize	= rnd.getInt(2, 16);

				data.setSize(w, h);
				tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);

				glTexSubImage2D(s_cubeMapFaces[face], ndx, x, y, w, h, m_format, m_dataType, data.getAccess().getDataPtr());
			}
		}
	}

	deUint32	m_format;
	deUint32	m_dataType;
};

// TexSubImage2D() to texture initialized with empty data
class TexSubImage2DEmptyTexCase : public TextureSpecCase
{
public:
	TexSubImage2DEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
		: TextureSpecCase	(context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
		, m_format			(format)
		, m_dataType		(dataType)
	{
	}

protected:
	void createTexture (void)
	{
		tcu::TextureFormat	fmt			= m_texFormat;
		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
		deUint32			tex			= 0;
		tcu::TextureLevel	data		(fmt);
		de::Random			rnd			(deStringHash(getName()));

		if (m_dataType == GL_HALF_FLOAT_OES && !m_half_float_oes)
			throw tcu::NotSupportedError("GL_OES_texture_half_float is not supported", "", __FILE__, __LINE__);

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_2D, tex);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

		// First allocate storage for each level.
		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_width >> ndx);
			int		levelH		= de::max(1, m_height >> ndx);

			glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, DE_NULL);
		}

		// Specify pixel data to all levels using glTexSubImage2D()
		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_width >> ndx);
			int		levelH		= de::max(1, m_height >> ndx);
			Vec4	gMin		= randomVector<4>(rnd);
			Vec4	gMax		= randomVector<4>(rnd);

			data.setSize(levelW, levelH);
			tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);

			glTexSubImage2D(GL_TEXTURE_2D, ndx, 0, 0, levelW, levelH, m_format, m_dataType, data.getAccess().getDataPtr());
		}
	}

	deUint32	m_format;
	deUint32	m_dataType;
};

// TexSubImage2D() to empty cubemap texture
class TexSubImageCubeEmptyTexCase : public TextureSpecCase
{
public:
	TexSubImageCubeEmptyTexCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
		: TextureSpecCase	(context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
		, m_format			(format)
		, m_dataType		(dataType)
	{
	}

protected:
	void createTexture (void)
	{
		tcu::TextureFormat	fmt			= m_texFormat;
		int					numLevels	= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
		deUint32			tex			= 0;
		tcu::TextureLevel	data		(fmt);
		de::Random			rnd			(deStringHash(getName()));

		DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.

		if (m_dataType == GL_HALF_FLOAT_OES && !m_half_float_oes)
			throw tcu::NotSupportedError("GL_OES_texture_half_float is not supported", "", __FILE__, __LINE__);

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

		// Specify storage for each level.
		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_width >> ndx);
			int		levelH		= de::max(1, m_height >> ndx);

			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
				glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelW, levelH, 0, m_format, m_dataType, DE_NULL);
		}

		// Specify data using glTexSubImage2D()
		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_width >> ndx);
			int		levelH		= de::max(1, m_height >> ndx);

			data.setSize(levelW, levelH);

			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
			{
				Vec4 gMin = randomVector<4>(rnd);
				Vec4 gMax = randomVector<4>(rnd);

				tcu::fillWithComponentGradients(data.getAccess(), gMin, gMax);

				glTexSubImage2D(s_cubeMapFaces[face], ndx, 0, 0, levelW, levelH, m_format, m_dataType, data.getAccess().getDataPtr());
			}
		}
	}

	deUint32	m_format;
	deUint32	m_dataType;
};

// TexSubImage2D() unpack alignment with 2D texture
class TexSubImage2DAlignCase : public TextureSpecCase
{
public:
	TexSubImage2DAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height, int subX, int subY, int subW, int subH, int alignment)
		: TextureSpecCase	(context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), 0 /* Mipmaps are never used */, width, height)
		, m_format			(format)
		, m_dataType		(dataType)
		, m_subX			(subX)
		, m_subY			(subY)
		, m_subW			(subW)
		, m_subH			(subH)
		, m_alignment		(alignment)
	{
	}

protected:
	void createTexture (void)
	{
		tcu::TextureFormat	fmt			= m_texFormat;
		deUint32			tex			= 0;
		vector<deUint8>		data;

		if (m_dataType == GL_HALF_FLOAT_OES && !m_half_float_oes)
			throw tcu::NotSupportedError("GL_OES_texture_half_float is not supported", "", __FILE__, __LINE__);

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_2D, tex);

		// Specify base level.
		data.resize(fmt.getPixelSize()*m_width*m_height);
		tcu::fillWithComponentGradients(tcu::PixelBufferAccess(fmt, m_width, m_height, 1, &data[0]), Vec4(0.0f), Vec4(1.0f));

		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		glTexImage2D(GL_TEXTURE_2D, 0, m_format, m_width, m_height, 0, m_format, m_dataType, &data[0]);

		// Re-specify subrectangle.
		int rowPitch = getRowPitch(fmt, m_subW, m_alignment);
		data.resize(rowPitch*m_subH);
		tcu::fillWithGrid(tcu::PixelBufferAccess(fmt, m_subW, m_subH, 1, rowPitch, 0, &data[0]), 4, Vec4(1.0f, 0.0f, 0.0f, 1.0f), Vec4(0.0f, 1.0f, 0.0f, 1.0f));

		glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
		glTexSubImage2D(GL_TEXTURE_2D, 0, m_subX, m_subY, m_subW, m_subH, m_format, m_dataType, &data[0]);
	}

	deUint32	m_format;
	deUint32	m_dataType;
	int			m_subX;
	int			m_subY;
	int			m_subW;
	int			m_subH;
	int			m_alignment;
};

// TexSubImage2D() unpack alignment with cubemap texture
class TexSubImageCubeAlignCase : public TextureSpecCase
{
public:
	TexSubImageCubeAlignCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, int width, int height, int subX, int subY, int subW, int subH, int alignment)
		: TextureSpecCase	(context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), 0 /* Mipmaps are never used */, width, height)
		, m_format			(format)
		, m_dataType		(dataType)
		, m_subX			(subX)
		, m_subY			(subY)
		, m_subW			(subW)
		, m_subH			(subH)
		, m_alignment		(alignment)
	{
	}

protected:
	void createTexture (void)
	{
		tcu::TextureFormat	fmt			= m_texFormat;
		deUint32			tex			= 0;
		vector<deUint8>		data;

		DE_ASSERT(m_width == m_height);

		if (m_dataType == GL_HALF_FLOAT_OES && !m_half_float_oes)
			throw tcu::NotSupportedError("GL_OES_texture_half_float is not supported", "", __FILE__, __LINE__);

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);

		// Specify base level.
		data.resize(fmt.getPixelSize()*m_width*m_height);
		tcu::fillWithComponentGradients(tcu::PixelBufferAccess(fmt, m_width, m_height, 1, &data[0]), Vec4(0.0f), Vec4(1.0f));

		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
			glTexImage2D(s_cubeMapFaces[face], 0, m_format, m_width, m_height, 0, m_format, m_dataType, &data[0]);

		// Re-specify subrectangle.
		int rowPitch = getRowPitch(fmt, m_subW, m_alignment);
		data.resize(rowPitch*m_subH);
		tcu::fillWithGrid(tcu::PixelBufferAccess(fmt, m_subW, m_subH, 1, rowPitch, 0, &data[0]), 4, Vec4(1.0f, 0.0f, 0.0f, 1.0f), Vec4(0.0f, 1.0f, 0.0f, 1.0f));

		glPixelStorei(GL_UNPACK_ALIGNMENT, m_alignment);
		for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
			glTexSubImage2D(s_cubeMapFaces[face], 0, m_subX, m_subY, m_subW, m_subH, m_format, m_dataType, &data[0]);
	}

	deUint32	m_format;
	deUint32	m_dataType;
	int			m_subX;
	int			m_subY;
	int			m_subW;
	int			m_subH;
	int			m_alignment;
};



// Basic CopyTexImage2D() with 2D texture usage
class BasicCopyTexImage2DCase : public TextureSpecCase
{
public:
	BasicCopyTexImage2DCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, deUint32 flags, int width, int height)
		: TextureSpecCase	(context, name, desc, TEXTURETYPE_2D, mapGLUnsizedInternalFormat(internalFormat), flags, width, height)
		, m_internalFormat	(internalFormat)
	{
	}

protected:
	void createTexture (void)
	{
		const tcu::RenderTarget&	renderTarget	= TestCase::m_context.getRenderContext().getRenderTarget();
		bool						targetHasRGB	= renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
		bool						targetHasAlpha	= renderTarget.getPixelFormat().alphaBits > 0;
		tcu::TextureFormat			fmt				= m_texFormat;
		bool						texHasRGB		= fmt.order != tcu::TextureFormat::A;
		bool						texHasAlpha		= fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
		int							numLevels		= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
		deUint32					tex				= 0;
		de::Random					rnd				(deStringHash(getName()));
		GradientShader				shader;
		deUint32					shaderID		= getCurrentContext()->createProgram(&shader);

		if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
			throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);

		// Fill render target with gradient.
		sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_2D, tex);

		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_width >> ndx);
			int		levelH		= de::max(1, m_height >> ndx);
			int		x			= rnd.getInt(0, getWidth()	- levelW);
			int		y			= rnd.getInt(0, getHeight()	- levelH);

			glCopyTexImage2D(GL_TEXTURE_2D, ndx, m_internalFormat, x, y, levelW, levelH, 0);
		}
	}

	deUint32 m_internalFormat;
};

// Basic CopyTexImage2D() with cubemap usage
class BasicCopyTexImageCubeCase : public TextureSpecCase
{
public:
	BasicCopyTexImageCubeCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, deUint32 flags, int width, int height)
		: TextureSpecCase	(context, name, desc, TEXTURETYPE_CUBE, mapGLUnsizedInternalFormat(internalFormat), flags, width, height)
		, m_internalFormat	(internalFormat)
	{
	}

protected:
	void createTexture (void)
	{
		const tcu::RenderTarget&	renderTarget	= TestCase::m_context.getRenderContext().getRenderTarget();
		bool						targetHasRGB	= renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
		bool						targetHasAlpha	= renderTarget.getPixelFormat().alphaBits > 0;
		tcu::TextureFormat			fmt				= m_texFormat;
		bool						texHasRGB		= fmt.order != tcu::TextureFormat::A;
		bool						texHasAlpha		= fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
		int							numLevels		= (m_flags & MIPMAPS) ? deLog2Floor32(m_width)+1 : 1;
		deUint32					tex				= 0;
		de::Random					rnd				(deStringHash(getName()));
		GradientShader				shader;
		deUint32					shaderID		= getCurrentContext()->createProgram(&shader);

		DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.

		if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
			throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);

		// Fill render target with gradient.
		sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);

		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int levelW = de::max(1, m_width >> ndx);
			int levelH = de::max(1, m_height >> ndx);

			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
			{
				int x = rnd.getInt(0, getWidth()	- levelW);
				int y = rnd.getInt(0, getHeight()	- levelH);

				glCopyTexImage2D(s_cubeMapFaces[face], ndx, m_internalFormat, x, y, levelW, levelH, 0);
			}
		}
	}

	deUint32 m_internalFormat;
};



// Basic CopyTexSubImage2D() with 2D texture usage
class BasicCopyTexSubImage2DCase : public TextureSpecCase
{
public:
	BasicCopyTexSubImage2DCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
		: TextureSpecCase	(context, name, desc, TEXTURETYPE_2D, glu::mapGLTransferFormat(format, dataType), flags, width, height)
		, m_format			(format)
		, m_dataType		(dataType)
	{
	}

protected:
	void createTexture (void)
	{
		const tcu::RenderTarget&	renderTarget	= TestCase::m_context.getRenderContext().getRenderTarget();
		bool						targetHasRGB	= renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
		bool						targetHasAlpha	= renderTarget.getPixelFormat().alphaBits > 0;
		tcu::TextureFormat			fmt				= m_texFormat;
		bool						texHasRGB		= fmt.order != tcu::TextureFormat::A;
		bool						texHasAlpha		= fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
		int							numLevels		= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
		deUint32					tex				= 0;
		tcu::TextureLevel			data			(fmt);
		de::Random					rnd				(deStringHash(getName()));
		GradientShader				shader;
		deUint32					shaderID		= getCurrentContext()->createProgram(&shader);

		if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
			throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);

		if (m_dataType == GL_HALF_FLOAT_OES && !m_half_float_oes)
			throw tcu::NotSupportedError("GL_OES_texture_half_float is not supported", "", __FILE__, __LINE__);

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_2D, tex);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

		// First specify full texture.
		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_width >> ndx);
			int		levelH		= de::max(1, m_height >> ndx);

			Vec4	colorA		= randomVector<4>(rnd);
			Vec4	colorB		= randomVector<4>(rnd);
			int		cellSize	= rnd.getInt(2, 16);

			data.setSize(levelW, levelH);
			tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);

			glTexImage2D(GL_TEXTURE_2D, ndx, m_format, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
		}

		// Fill render target with gradient.
		sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));

		// Re-specify parts of each level.
		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_width >> ndx);
			int		levelH		= de::max(1, m_height >> ndx);

			int		w			= rnd.getInt(1, levelW);
			int		h			= rnd.getInt(1, levelH);
			int		xo			= rnd.getInt(0, levelW-w);
			int		yo			= rnd.getInt(0, levelH-h);

			int		x			= rnd.getInt(0, getWidth() - w);
			int		y			= rnd.getInt(0, getHeight() - h);

			glCopyTexSubImage2D(GL_TEXTURE_2D, ndx, xo, yo, x, y, w, h);
		}
	}

	deUint32	m_format;
	deUint32	m_dataType;
};

// Basic CopyTexSubImage2D() with cubemap usage
class BasicCopyTexSubImageCubeCase : public TextureSpecCase
{
public:
	BasicCopyTexSubImageCubeCase (Context& context, const char* name, const char* desc, deUint32 format, deUint32 dataType, deUint32 flags, int width, int height)
		: TextureSpecCase	(context, name, desc, TEXTURETYPE_CUBE, glu::mapGLTransferFormat(format, dataType), flags, width, height)
		, m_format			(format)
		, m_dataType		(dataType)
	{
	}

protected:
	void createTexture (void)
	{
		const tcu::RenderTarget&	renderTarget	= TestCase::m_context.getRenderContext().getRenderTarget();
		bool						targetHasRGB	= renderTarget.getPixelFormat().redBits > 0 && renderTarget.getPixelFormat().greenBits > 0 && renderTarget.getPixelFormat().blueBits > 0;
		bool						targetHasAlpha	= renderTarget.getPixelFormat().alphaBits > 0;
		tcu::TextureFormat			fmt				= m_texFormat;
		bool						texHasRGB		= fmt.order != tcu::TextureFormat::A;
		bool						texHasAlpha		= fmt.order == tcu::TextureFormat::RGBA || fmt.order == tcu::TextureFormat::LA || fmt.order == tcu::TextureFormat::A;
		int							numLevels		= (m_flags & MIPMAPS) ? de::max(deLog2Floor32(m_width), deLog2Floor32(m_height))+1 : 1;
		deUint32					tex				= 0;
		tcu::TextureLevel			data			(fmt);
		de::Random					rnd				(deStringHash(getName()));
		GradientShader				shader;
		deUint32					shaderID		= getCurrentContext()->createProgram(&shader);

		DE_ASSERT(m_width == m_height); // Non-square cubemaps are not supported by GLES2.

		if ((texHasRGB && !targetHasRGB) || (texHasAlpha && !targetHasAlpha))
			throw tcu::NotSupportedError("Copying from current framebuffer is not supported", "", __FILE__, __LINE__);

		if (m_dataType == GL_HALF_FLOAT_OES && !m_half_float_oes)
			throw tcu::NotSupportedError("GL_OES_texture_half_float is not supported", "", __FILE__, __LINE__);

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_width >> ndx);
			int		levelH		= de::max(1, m_height >> ndx);

			data.setSize(levelW, levelH);

			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
			{
				Vec4	colorA		= randomVector<4>(rnd);
				Vec4	colorB		= randomVector<4>(rnd);
				int		cellSize	= rnd.getInt(2, 16);

				tcu::fillWithGrid(data.getAccess(), cellSize, colorA, colorB);
				glTexImage2D(s_cubeMapFaces[face], ndx, m_format, levelW, levelH, 0, m_format, m_dataType, data.getAccess().getDataPtr());
			}
		}

		// Fill render target with gradient.
		sglr::drawQuad(*getCurrentContext(), shaderID, tcu::Vec3(-1.0f, -1.0f, 0.0f), tcu::Vec3(1.0f, 1.0f, 0.0f));

		// Re-specify parts of each face and level.
		for (int ndx = 0; ndx < numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_width >> ndx);
			int		levelH		= de::max(1, m_height >> ndx);

			for (int face = 0; face < DE_LENGTH_OF_ARRAY(s_cubeMapFaces); face++)
			{
				int		w			= rnd.getInt(1, levelW);
				int		h			= rnd.getInt(1, levelH);
				int		xo			= rnd.getInt(0, levelW-w);
				int		yo			= rnd.getInt(0, levelH-h);

				int		x			= rnd.getInt(0, getWidth() - w);
				int		y			= rnd.getInt(0, getHeight() - h);

				glCopyTexSubImage2D(s_cubeMapFaces[face], ndx, xo, yo, x, y, w, h);
			}
		}
	}

	deUint32	m_format;
	deUint32	m_dataType;
};

TextureSpecificationTests::TextureSpecificationTests (Context& context)
	: TestCaseGroup(context, "specification", "Texture Specification Tests")
{
}

TextureSpecificationTests::~TextureSpecificationTests (void)
{
}

void TextureSpecificationTests::init (void)
{
	struct
	{
		const char*	name;
		deUint32	format;
		deUint32	dataType;
	} texFormats[] =
	{
		{ "a8",			GL_ALPHA,			GL_UNSIGNED_BYTE },
		{ "l8",			GL_LUMINANCE,		GL_UNSIGNED_BYTE },
		{ "la88",		GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE },
		{ "rgb565",		GL_RGB,				GL_UNSIGNED_SHORT_5_6_5 },
		{ "rgb888",		GL_RGB,				GL_UNSIGNED_BYTE },
		{ "rgba4444",	GL_RGBA,			GL_UNSIGNED_SHORT_4_4_4_4 },
		{ "rgba5551",	GL_RGBA,			GL_UNSIGNED_SHORT_5_5_5_1 },
		{ "rgba8888",	GL_RGBA,			GL_UNSIGNED_BYTE },
		{ "rgba16f",	GL_RGBA,			GL_HALF_FLOAT_OES },
		{ "rgb16f",		GL_RGB,				GL_HALF_FLOAT_OES },
		{ "la16f",		GL_LUMINANCE_ALPHA,	GL_HALF_FLOAT_OES },
		{ "l16f",		GL_LUMINANCE,		GL_HALF_FLOAT_OES },
		{ "a16f",		GL_ALPHA,			GL_HALF_FLOAT_OES }
	};

	// Basic TexImage2D usage.
	{
		tcu::TestCaseGroup* basicTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_teximage2d", "Basic glTexImage2D() usage");
		addChild(basicTexImageGroup);
		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(texFormats); formatNdx++)
		{
			const char*	fmtName		= texFormats[formatNdx].name;
			deUint32	format		= texFormats[formatNdx].format;
			deUint32	dataType	= texFormats[formatNdx].dataType;
			const int	tex2DWidth	= 64;
			const int	tex2DHeight	= 128;
			const int	texCubeSize	= 64;

			basicTexImageGroup->addChild(new BasicTexImage2DCase	(m_context,	(string(fmtName) + "_2d").c_str(),		"",	format, dataType, MIPMAPS, tex2DWidth, tex2DHeight));
			basicTexImageGroup->addChild(new BasicTexImageCubeCase	(m_context,	(string(fmtName) + "_cube").c_str(),	"",	format, dataType, MIPMAPS, texCubeSize, texCubeSize));
		}
	}

	// Randomized TexImage2D order.
	{
		tcu::TestCaseGroup* randomTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "random_teximage2d", "Randomized glTexImage2D() usage");
		addChild(randomTexImageGroup);

		de::Random rnd(9);

		// 2D cases.
		for (int ndx = 0; ndx < 10; ndx++)
		{
			int		formatNdx	= rnd.getInt(0, DE_LENGTH_OF_ARRAY(texFormats)-1);
			int		width		= 1 << rnd.getInt(2, 8);
			int		height		= 1 << rnd.getInt(2, 8);

			randomTexImageGroup->addChild(new RandomOrderTexImage2DCase(m_context, (string("2d_") + de::toString(ndx)).c_str(), "", texFormats[formatNdx].format, texFormats[formatNdx].dataType, MIPMAPS, width, height));
		}

		// Cubemap cases.
		for (int ndx = 0; ndx < 10; ndx++)
		{
			int		formatNdx	= rnd.getInt(0, DE_LENGTH_OF_ARRAY(texFormats)-1);
			int		size		= 1 << rnd.getInt(2, 8);

			randomTexImageGroup->addChild(new RandomOrderTexImageCubeCase(m_context, (string("cube_") + de::toString(ndx)).c_str(), "", texFormats[formatNdx].format, texFormats[formatNdx].dataType, MIPMAPS, size, size));
		}
	}

	// TexImage2D unpack alignment.
	{
		tcu::TestCaseGroup* alignGroup = new tcu::TestCaseGroup(m_testCtx, "teximage2d_align", "glTexImage2D() unpack alignment tests");
		addChild(alignGroup);

		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_l8_4_8",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			MIPMAPS,	 4, 8, 8));
		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_l8_63_1",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			0,			63, 30, 1));
		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_l8_63_2",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			0,			63, 30, 2));
		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_l8_63_4",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			0,			63, 30, 4));
		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_l8_63_8",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			0,			63, 30, 8));
		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba4444_51_1",		"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	0,			51, 30, 1));
		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba4444_51_2",		"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	0,			51, 30, 2));
		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba4444_51_4",		"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	0,			51, 30, 4));
		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba4444_51_8",		"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	0,			51, 30, 8));
		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgb888_39_1",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			0,			39, 43, 1));
		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgb888_39_2",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			0,			39, 43, 2));
		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgb888_39_4",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			0,			39, 43, 4));
		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgb888_39_8",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			0,			39, 43, 8));
		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba8888_47_1",		"",	GL_RGBA,		GL_UNSIGNED_BYTE,			0,			47, 27, 1));
		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba8888_47_2",		"",	GL_RGBA,		GL_UNSIGNED_BYTE,			0,			47, 27, 2));
		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba8888_47_4",		"",	GL_RGBA,		GL_UNSIGNED_BYTE,			0,			47, 27, 4));
		alignGroup->addChild(new TexImage2DAlignCase	(m_context, "2d_rgba8888_47_8",		"",	GL_RGBA,		GL_UNSIGNED_BYTE,			0,			47, 27, 8));

		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_l8_4_8",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			MIPMAPS,	 4, 4, 8));
		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_l8_63_1",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			0,			63, 63, 1));
		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_l8_63_2",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			0,			63, 63, 2));
		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_l8_63_4",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			0,			63, 63, 4));
		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_l8_63_8",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			0,			63, 63, 8));
		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba4444_51_1",	"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	0,			51, 51, 1));
		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba4444_51_2",	"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	0,			51, 51, 2));
		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba4444_51_4",	"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	0,			51, 51, 4));
		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba4444_51_8",	"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	0,			51, 51, 8));
		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgb888_39_1",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			0,			39, 39, 1));
		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgb888_39_2",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			0,			39, 39, 2));
		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgb888_39_4",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			0,			39, 39, 4));
		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgb888_39_8",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			0,			39, 39, 8));
		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba8888_47_1",	"",	GL_RGBA,		GL_UNSIGNED_BYTE,			0,			47, 47, 1));
		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba8888_47_2",	"",	GL_RGBA,		GL_UNSIGNED_BYTE,			0,			47, 47, 2));
		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba8888_47_4",	"",	GL_RGBA,		GL_UNSIGNED_BYTE,			0,			47, 47, 4));
		alignGroup->addChild(new TexImageCubeAlignCase	(m_context, "cube_rgba8888_47_8",	"",	GL_RGBA,		GL_UNSIGNED_BYTE,			0,			47, 47, 8));
	}

	// Basic TexSubImage2D usage.
	{
		tcu::TestCaseGroup* basicTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_texsubimage2d", "Basic glTexSubImage2D() usage");
		addChild(basicTexSubImageGroup);
		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(texFormats); formatNdx++)
		{
			const char*	fmtName		= texFormats[formatNdx].name;
			deUint32	format		= texFormats[formatNdx].format;
			deUint32	dataType	= texFormats[formatNdx].dataType;
			const int	tex2DWidth	= 64;
			const int	tex2DHeight	= 128;
			const int	texCubeSize	= 64;

			basicTexSubImageGroup->addChild(new BasicTexSubImage2DCase		(m_context,	(string(fmtName) + "_2d").c_str(),		"",	format, dataType, MIPMAPS, tex2DWidth, tex2DHeight));
			basicTexSubImageGroup->addChild(new BasicTexSubImageCubeCase	(m_context,	(string(fmtName) + "_cube").c_str(),	"",	format, dataType, MIPMAPS, texCubeSize, texCubeSize));
		}
	}

	// TexSubImage2D to empty texture.
	{
		tcu::TestCaseGroup* texSubImageEmptyTexGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_empty_tex", "glTexSubImage2D() to texture that has storage but no data");
		addChild(texSubImageEmptyTexGroup);
		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(texFormats); formatNdx++)
		{
			const char*	fmtName		= texFormats[formatNdx].name;
			deUint32	format		= texFormats[formatNdx].format;
			deUint32	dataType	= texFormats[formatNdx].dataType;
			const int	tex2DWidth	= 64;
			const int	tex2DHeight	= 32;
			const int	texCubeSize	= 32;

			texSubImageEmptyTexGroup->addChild(new TexSubImage2DEmptyTexCase	(m_context,	(string(fmtName) + "_2d").c_str(),		"",	format, dataType, MIPMAPS, tex2DWidth, tex2DHeight));
			texSubImageEmptyTexGroup->addChild(new TexSubImageCubeEmptyTexCase	(m_context,	(string(fmtName) + "_cube").c_str(),	"",	format, dataType, MIPMAPS, texCubeSize, texCubeSize));
		}
	}

	// TexSubImage2D alignment cases.
	{
		tcu::TestCaseGroup* alignGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage2d_align", "glTexSubImage2D() unpack alignment tests");
		addChild(alignGroup);

		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_l8_1_1",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64, 13, 17,  1,  6, 1));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_l8_1_2",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64, 13, 17,  1,  6, 2));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_l8_1_4",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64, 13, 17,  1,  6, 4));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_l8_1_8",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64, 13, 17,  1,  6, 8));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_l8_63_1",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64,  1,  9, 63, 30, 1));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_l8_63_2",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64,  1,  9, 63, 30, 2));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_l8_63_4",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64,  1,  9, 63, 30, 4));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_l8_63_8",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64,  1,  9, 63, 30, 8));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba4444_51_1",		"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	64, 64,  7, 29, 51, 30, 1));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba4444_51_2",		"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	64, 64,  7, 29, 51, 30, 2));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba4444_51_4",		"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	64, 64,  7, 29, 51, 30, 4));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba4444_51_8",		"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	64, 64,  7, 29, 51, 30, 8));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgb888_39_1",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			64, 64, 11,  8, 39, 43, 1));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgb888_39_2",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			64, 64, 11,  8, 39, 43, 2));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgb888_39_4",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			64, 64, 11,  8, 39, 43, 4));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgb888_39_8",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			64, 64, 11,  8, 39, 43, 8));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba8888_47_1",		"",	GL_RGBA,		GL_UNSIGNED_BYTE,			64, 64, 10,  1, 47, 27, 1));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba8888_47_2",		"",	GL_RGBA,		GL_UNSIGNED_BYTE,			64, 64, 10,  1, 47, 27, 2));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba8888_47_4",		"",	GL_RGBA,		GL_UNSIGNED_BYTE,			64, 64, 10,  1, 47, 27, 4));
		alignGroup->addChild(new TexSubImage2DAlignCase		(m_context, "2d_rgba8888_47_8",		"",	GL_RGBA,		GL_UNSIGNED_BYTE,			64, 64, 10,  1, 47, 27, 8));

		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_l8_1_1",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64, 13, 17,  1,  6, 1));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_l8_1_2",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64, 13, 17,  1,  6, 2));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_l8_1_4",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64, 13, 17,  1,  6, 4));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_l8_1_8",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64, 13, 17,  1,  6, 8));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_l8_63_1",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64,  1,  9, 63, 30, 1));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_l8_63_2",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64,  1,  9, 63, 30, 2));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_l8_63_4",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64,  1,  9, 63, 30, 4));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_l8_63_8",			"",	GL_LUMINANCE,	GL_UNSIGNED_BYTE,			64, 64,  1,  9, 63, 30, 8));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba4444_51_1",	"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	64, 64,  7, 29, 51, 30, 1));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba4444_51_2",	"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	64, 64,  7, 29, 51, 30, 2));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba4444_51_4",	"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	64, 64,  7, 29, 51, 30, 4));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba4444_51_8",	"",	GL_RGBA,		GL_UNSIGNED_SHORT_4_4_4_4,	64, 64,  7, 29, 51, 30, 8));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgb888_39_1",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			64, 64, 11,  8, 39, 43, 1));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgb888_39_2",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			64, 64, 11,  8, 39, 43, 2));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgb888_39_4",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			64, 64, 11,  8, 39, 43, 4));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgb888_39_8",		"",	GL_RGB,			GL_UNSIGNED_BYTE,			64, 64, 11,  8, 39, 43, 8));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba8888_47_1",	"",	GL_RGBA,		GL_UNSIGNED_BYTE,			64, 64, 10,  1, 47, 27, 1));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba8888_47_2",	"",	GL_RGBA,		GL_UNSIGNED_BYTE,			64, 64, 10,  1, 47, 27, 2));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba8888_47_4",	"",	GL_RGBA,		GL_UNSIGNED_BYTE,			64, 64, 10,  1, 47, 27, 4));
		alignGroup->addChild(new TexSubImageCubeAlignCase	(m_context, "cube_rgba8888_47_8",	"",	GL_RGBA,		GL_UNSIGNED_BYTE,			64, 64, 10,  1, 47, 27, 8));
	}

	// Basic glCopyTexImage2D() cases
	{
		tcu::TestCaseGroup* copyTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_copyteximage2d", "Basic glCopyTexImage2D() usage");
		addChild(copyTexImageGroup);

		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_alpha",				"",	GL_ALPHA,			MIPMAPS,	128, 64));
		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_luminance",			"",	GL_LUMINANCE,		MIPMAPS,	128, 64));
		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_luminance_alpha",	"",	GL_LUMINANCE_ALPHA,	MIPMAPS,	128, 64));
		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_rgb",				"",	GL_RGB,				MIPMAPS,	128, 64));
		copyTexImageGroup->addChild(new BasicCopyTexImage2DCase		(m_context, "2d_rgba",				"",	GL_RGBA,			MIPMAPS,	128, 64));

		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_alpha",			"",	GL_ALPHA,			MIPMAPS,	64, 64));
		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_luminance",		"",	GL_LUMINANCE,		MIPMAPS,	64, 64));
		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_luminance_alpha",	"",	GL_LUMINANCE_ALPHA,	MIPMAPS,	64, 64));
		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_rgb",				"",	GL_RGB,				MIPMAPS,	64, 64));
		copyTexImageGroup->addChild(new BasicCopyTexImageCubeCase	(m_context, "cube_rgba",			"",	GL_RGBA,			MIPMAPS,	64, 64));
	}

	// Basic glCopyTexSubImage2D() cases
	{
		tcu::TestCaseGroup* copyTexSubImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_copytexsubimage2d", "Basic glCopyTexSubImage2D() usage");
		addChild(copyTexSubImageGroup);

		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_alpha",				"",	GL_ALPHA,			GL_UNSIGNED_BYTE, MIPMAPS, 128, 64));
		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_luminance",			"",	GL_LUMINANCE,		GL_UNSIGNED_BYTE, MIPMAPS, 128, 64));
		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_luminance_alpha",	"",	GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE, MIPMAPS, 128, 64));
		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_rgb",				"",	GL_RGB,				GL_UNSIGNED_BYTE, MIPMAPS, 128, 64));
		copyTexSubImageGroup->addChild(new BasicCopyTexSubImage2DCase	(m_context, "2d_rgba",				"",	GL_RGBA,			GL_UNSIGNED_BYTE, MIPMAPS, 128, 64));

		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_alpha",			"",	GL_ALPHA,			GL_UNSIGNED_BYTE, MIPMAPS, 64, 64));
		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_luminance",		"",	GL_LUMINANCE,		GL_UNSIGNED_BYTE, MIPMAPS, 64, 64));
		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_luminance_alpha",	"",	GL_LUMINANCE_ALPHA,	GL_UNSIGNED_BYTE, MIPMAPS, 64, 64));
		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_rgb",				"",	GL_RGB,				GL_UNSIGNED_BYTE, MIPMAPS, 64, 64));
		copyTexSubImageGroup->addChild(new BasicCopyTexSubImageCubeCase	(m_context, "cube_rgba",			"",	GL_RGBA,			GL_UNSIGNED_BYTE, MIPMAPS, 64, 64));
	}
}

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