/*-------------------------------------------------------------------------
 * 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 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 "es31fTextureSpecificationTests.hpp"
#include "tcuTestLog.hpp"
#include "tcuImageCompare.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuVectorUtil.hpp"
#include "gluStrUtil.hpp"
#include "gluTexture.hpp"
#include "gluTextureUtil.hpp"
#include "sglrContextUtil.hpp"
#include "sglrContextWrapper.hpp"
#include "sglrGLContext.hpp"
#include "sglrReferenceContext.hpp"
#include "glsTextureTestUtil.hpp"
#include "deRandom.hpp"
#include "deStringUtil.hpp"

// \todo [2012-04-29 pyry] Should be named SglrUtil
#include "es31fFboTestUtil.hpp"

#include "glwEnums.hpp"

namespace deqp
{
namespace gles31
{
namespace Functional
{

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

enum
{
	VIEWPORT_WIDTH	= 256,
	VIEWPORT_HEIGHT	= 256
};

static inline int maxLevelCount (int size)
{
	return (int)deLog2Floor32(size)+1;
}

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::CubeFace getCubeFaceFromNdx (int ndx)
{
	switch (ndx)
	{
		case 0:	return tcu::CUBEFACE_POSITIVE_X;
		case 1:	return tcu::CUBEFACE_NEGATIVE_X;
		case 2:	return tcu::CUBEFACE_POSITIVE_Y;
		case 3:	return tcu::CUBEFACE_NEGATIVE_Y;
		case 4:	return tcu::CUBEFACE_POSITIVE_Z;
		case 5:	return tcu::CUBEFACE_NEGATIVE_Z;
		default:
			DE_ASSERT(false);
			return tcu::CUBEFACE_LAST;
	}
}

class TextureSpecCase : public TestCase, public sglr::ContextWrapper
{
public:
						TextureSpecCase			(Context& context, const char* name, const char* desc);
						~TextureSpecCase		(void);

	IterateResult		iterate					(void);

protected:
	virtual bool		checkExtensionSupport	(void)	{ return true; }

	virtual void		createTexture			(void)																= DE_NULL;
	virtual void		verifyTexture			(sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext)	= DE_NULL;

	// Utilities.
	void				renderTex				(tcu::Surface& dst, deUint32 program, int width, int height);
	void				readPixels				(tcu::Surface& dst, int x, int y, int width, int height);

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

TextureSpecCase::TextureSpecCase (Context& context, const char* name, const char* desc)
	: TestCase(context, name, desc)
{
}

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

	if (renderTarget.getWidth() < VIEWPORT_WIDTH || renderTarget.getHeight() < VIEWPORT_HEIGHT)
		throw tcu::NotSupportedError("Too small viewport", "", __FILE__, __LINE__);

	if (!checkExtensionSupport())
		throw tcu::NotSupportedError("Extension not supported", "", __FILE__, __LINE__);

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

	// Contexts.
	sglr::GLContext					gles31Context	(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*)&gles31Context);
		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 GLES3.1 and reference contexts.
	for (int ndx = 0; ndx < 2; ndx++)
	{
		setContext(ndx ? (sglr::Context*)&refContext : (sglr::Context*)&gles31Context);
		createTexture();
		TCU_CHECK(glGetError() == GL_NO_ERROR);
	}

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

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

	// Verify results.
	verifyTexture(gles31Context, refContext);

	return STOP;
}

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

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

	sglr::drawQuad(*getCurrentContext(), program, 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());
}

class TextureCubeArraySpecCase : public TextureSpecCase
{
public:
							TextureCubeArraySpecCase	(Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int size, int depth, int numLevels);
							~TextureCubeArraySpecCase	(void);

protected:
	virtual bool			checkExtensionSupport		(void);
	virtual void			verifyTexture				(sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext);

	tcu::TextureFormat		m_texFormat;
	tcu::TextureFormatInfo	m_texFormatInfo;
	int						m_size;
	int						m_depth;
	int						m_numLevels;
};

TextureCubeArraySpecCase::TextureCubeArraySpecCase (Context& context, const char* name, const char* desc, const tcu::TextureFormat& format, int size, int depth, int numLevels)
	: TextureSpecCase		(context, name, desc)
	, m_texFormat			(format)
	, m_texFormatInfo		(tcu::getTextureFormatInfo(format))
	, m_size				(size)
	, m_depth				(depth)
	, m_numLevels			(numLevels)
{
}

TextureCubeArraySpecCase::~TextureCubeArraySpecCase (void)
{
}

bool TextureCubeArraySpecCase::checkExtensionSupport (void)
{
	return m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_cube_map_array");
}

void TextureCubeArraySpecCase::verifyTexture (sglr::GLContext& gles3Context, sglr::ReferenceContext& refContext)
{
	TextureCubeArrayShader	shader			(glu::getSamplerCubeArrayType(m_texFormat), glu::TYPE_FLOAT_VEC4);
	deUint32				shaderIDgles	= gles3Context.createProgram(&shader);
	deUint32				shaderIDRef		= refContext.createProgram(&shader);

	shader.setTexScaleBias(m_texFormatInfo.lookupScale, m_texFormatInfo.lookupBias);

	// Set state.
	for (int ndx = 0; ndx < 2; ndx++)
	{
		sglr::Context* ctx = ndx ? static_cast<sglr::Context*>(&refContext) : static_cast<sglr::Context*>(&gles3Context);

		setContext(ctx);

		glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MIN_FILTER,	GL_NEAREST_MIPMAP_NEAREST);
		glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAG_FILTER,	GL_NEAREST);
		glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_WRAP_R,		GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_MAX_LEVEL,	m_numLevels-1);
	}

	for (int layerFaceNdx = 0; layerFaceNdx < m_depth; layerFaceNdx++)
	{
		const int			layerNdx	= layerFaceNdx / 6;
		const tcu::CubeFace	face		= getCubeFaceFromNdx(layerFaceNdx % 6);
		bool				layerOk		= true;

		shader.setLayer(layerNdx);
		shader.setFace(face);

		for (int levelNdx = 0; levelNdx < m_numLevels; levelNdx++)
		{
			int				levelSize	= de::max(1, m_size	>> levelNdx);
			tcu::Surface	reference;
			tcu::Surface	result;

			if (levelSize <= 2)
				continue; // Fuzzy compare doesn't work for images this small.

			for (int ndx = 0; ndx < 2; ndx++)
			{
				tcu::Surface&	dst			= ndx ? reference									: result;
				sglr::Context*	ctx			= ndx ? static_cast<sglr::Context*>(&refContext)	: static_cast<sglr::Context*>(&gles3Context);
				deUint32		shaderID	= ndx ? shaderIDRef									: shaderIDgles;

				setContext(ctx);
				shader.setUniforms(*ctx, shaderID);
				renderTex(dst, shaderID, levelSize, levelSize);
			}

			const float		threshold		= 0.02f;
			string			levelStr		= de::toString(levelNdx);
			string			layerFaceStr	= de::toString(layerFaceNdx);
			string			name			= string("LayerFace") + layerFaceStr + "Level" + levelStr;
			string			desc			= string("Layer-face ") + layerFaceStr + ", Level " + levelStr;
			bool			isFaceOk		= tcu::fuzzyCompare(m_testCtx.getLog(), name.c_str(), desc.c_str(), reference, result, threshold,
																(levelNdx == 0 && layerFaceNdx == 0) == 0 ? tcu::COMPARE_LOG_RESULT : tcu::COMPARE_LOG_ON_ERROR);

			if (!isFaceOk)
			{
				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image comparison failed");
				layerOk = false;
				break;
			}
		}

		if (!layerOk)
			break;
	}
}

// Basic TexImage3D() with cube map array texture usage
class BasicTexImageCubeArrayCase : public TextureCubeArraySpecCase
{
public:
	BasicTexImageCubeArrayCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int numLayers)
		: TextureCubeArraySpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, numLayers, maxLevelCount(size))
		, m_internalFormat			(internalFormat)
	{
	}

protected:
	void createTexture (void)
	{
		deUint32				tex			= 0;
		de::Random				rnd			(deStringHash(getName()));
		glu::TransferFormat		transferFmt	= glu::getTransferFormat(m_texFormat);
		tcu::TextureLevel		levelData	(glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));

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

		for (int ndx = 0; ndx < m_numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_size	>> ndx);
			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);

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

			glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, m_internalFormat, levelW, levelW, m_depth, 0, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
		}
	}

	deUint32 m_internalFormat;
};

// Basic glTexStorage3D() with cube map array texture usage
class BasicTexStorageCubeArrayCase : public TextureCubeArraySpecCase
{
public:
	BasicTexStorageCubeArrayCase (Context& context, const char* name, const char* desc, deUint32 internalFormat, int size, int numLayers, int numLevels)
		: TextureCubeArraySpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, numLayers, numLevels)
		, m_internalFormat			(internalFormat)
	{
	}

protected:
	void createTexture (void)
	{
		deUint32				tex			= 0;
		de::Random				rnd			(deStringHash(getName()));
		glu::TransferFormat		transferFmt	= glu::getTransferFormat(m_texFormat);
		tcu::TextureLevel		levelData	(glu::mapGLTransferFormat(transferFmt.format, transferFmt.dataType));

		glGenTextures	(1, &tex);
		glBindTexture	(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
		glTexStorage3D	(GL_TEXTURE_CUBE_MAP_ARRAY, m_numLevels, m_internalFormat, m_size, m_size, m_depth);

		glPixelStorei	(GL_UNPACK_ALIGNMENT, 1);

		for (int ndx = 0; ndx < m_numLevels; ndx++)
		{
			int		levelW		= de::max(1, m_size	>> ndx);
			Vec4	gMin		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
			Vec4	gMax		= randomVector<4>(rnd, m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);

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

			glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, 0, 0, 0, levelW, levelW, m_depth, transferFmt.format, transferFmt.dataType, levelData.getAccess().getDataPtr());
		}
	}

	deUint32 m_internalFormat;
};

// Pixel buffer object cases.

// TexImage3D() cube map array from pixel buffer object.
class TexImageCubeArrayBufferCase : public TextureCubeArraySpecCase
{
public:
	TexImageCubeArrayBufferCase (Context&		context,
							   const char*	name,
							   const char*	desc,
							   deUint32		internalFormat,
							   int			size,
							   int			depth,
							   int			imageHeight,
							   int			rowLength,
							   int			skipImages,
							   int			skipRows,
							   int			skipPixels,
							   int			alignment,
							   int			offset)
		: TextureCubeArraySpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, depth, 1)
		, m_internalFormat			(internalFormat)
		, m_imageHeight				(imageHeight)
		, m_rowLength				(rowLength)
		, m_skipImages				(skipImages)
		, m_skipRows				(skipRows)
		, m_skipPixels				(skipPixels)
		, m_alignment				(alignment)
		, m_offset					(offset)
	{
	}

protected:
	void createTexture (void)
	{
		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
		int						pixelSize		= m_texFormat.getPixelSize();
		int						rowLength		= m_rowLength > 0 ? m_rowLength : m_size;
		int						rowPitch		= deAlign32(rowLength*pixelSize, m_alignment);
		int						imageHeight		= m_imageHeight > 0 ? m_imageHeight : m_size;
		int						slicePitch		= imageHeight*rowPitch;
		deUint32				tex				= 0;
		deUint32				buf				= 0;
		vector<deUint8>			data;

		DE_ASSERT(m_numLevels == 1);

		// Fill data with grid.
		data.resize(slicePitch*(m_depth+m_skipImages) + m_offset);
		{
			Vec4	cScale		= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
			Vec4	cBias		= m_texFormatInfo.valueMin;
			Vec4	colorA		= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
			Vec4	colorB		= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;

			tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, m_depth, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
		}

		glGenBuffers(1, &buf);
		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
		glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);

		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,	m_imageHeight);
		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
		glPixelStorei(GL_UNPACK_SKIP_IMAGES,	m_skipImages);
		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
		glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, m_internalFormat, m_size, m_size, m_depth, 0, transferFmt.format, transferFmt.dataType, (const void*)(deUintptr)m_offset);
	}

	deUint32	m_internalFormat;
	int			m_imageHeight;
	int			m_rowLength;
	int			m_skipImages;
	int			m_skipRows;
	int			m_skipPixels;
	int			m_alignment;
	int			m_offset;
};

// TexSubImage3D() cube map array PBO case.
class TexSubImageCubeArrayBufferCase : public TextureCubeArraySpecCase
{
public:
	TexSubImageCubeArrayBufferCase (Context&		context,
								 const char*	name,
								 const char*	desc,
								 deUint32		internalFormat,
								 int			size,
								 int			depth,
								 int			subX,
								 int			subY,
								 int			subZ,
								 int			subW,
								 int			subH,
								 int			subD,
								 int			imageHeight,
								 int			rowLength,
								 int			skipImages,
								 int			skipRows,
								 int			skipPixels,
								 int			alignment,
								 int			offset)
		: TextureCubeArraySpecCase	(context, name, desc, glu::mapGLInternalFormat(internalFormat), size, depth, 1)
		, m_internalFormat			(internalFormat)
		, m_subX					(subX)
		, m_subY					(subY)
		, m_subZ					(subZ)
		, m_subW					(subW)
		, m_subH					(subH)
		, m_subD					(subD)
		, m_imageHeight				(imageHeight)
		, m_rowLength				(rowLength)
		, m_skipImages				(skipImages)
		, m_skipRows				(skipRows)
		, m_skipPixels				(skipPixels)
		, m_alignment				(alignment)
		, m_offset					(offset)
	{
	}

protected:
	void createTexture (void)
	{
		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
		int						pixelSize		= m_texFormat.getPixelSize();
		deUint32				tex				= 0;
		deUint32				buf				= 0;
		vector<deUint8>			data;

		DE_ASSERT(m_numLevels == 1);

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

		// Fill with gradient.
		{
			int		rowPitch		= deAlign32(pixelSize*m_size,  4);
			int		slicePitch		= rowPitch*m_size;

			data.resize(slicePitch*m_depth);
			tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, m_depth, rowPitch, slicePitch, &data[0]), m_texFormatInfo.valueMin, m_texFormatInfo.valueMax);
		}

		glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, m_internalFormat, m_size, m_size, m_depth, 0, transferFmt.format, transferFmt.dataType, &data[0]);

		// Fill data with grid.
		{
			int		rowLength		= m_rowLength > 0 ? m_rowLength : m_subW;
			int		rowPitch		= deAlign32(rowLength*pixelSize, m_alignment);
			int		imageHeight		= m_imageHeight > 0 ? m_imageHeight : m_subH;
			int		slicePitch		= imageHeight*rowPitch;
			Vec4	cScale			= m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
			Vec4	cBias			= m_texFormatInfo.valueMin;
			Vec4	colorA			= Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias;
			Vec4	colorB			= Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias;

			data.resize(slicePitch*(m_depth+m_skipImages) + m_offset);
			tcu::fillWithGrid(tcu::PixelBufferAccess(m_texFormat, m_subW, m_subH, m_subD, rowPitch, slicePitch, &data[0] + m_skipImages*slicePitch + m_skipRows*rowPitch + m_skipPixels*pixelSize + m_offset), 4, colorA, colorB);
		}

		glGenBuffers(1, &buf);
		glBindBuffer(GL_PIXEL_UNPACK_BUFFER,	buf);
		glBufferData(GL_PIXEL_UNPACK_BUFFER,	(int)data.size(), &data[0], GL_STATIC_DRAW);

		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,	m_imageHeight);
		glPixelStorei(GL_UNPACK_ROW_LENGTH,		m_rowLength);
		glPixelStorei(GL_UNPACK_SKIP_IMAGES,	m_skipImages);
		glPixelStorei(GL_UNPACK_SKIP_ROWS,		m_skipRows);
		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	m_skipPixels);
		glPixelStorei(GL_UNPACK_ALIGNMENT,		m_alignment);
		glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, m_subX, m_subY, m_subZ, m_subW, m_subH, m_subD, transferFmt.format, transferFmt.dataType, (const void*)(deIntptr)m_offset);
	}

	deUint32	m_internalFormat;
	int			m_subX;
	int			m_subY;
	int			m_subZ;
	int			m_subW;
	int			m_subH;
	int			m_subD;
	int			m_imageHeight;
	int			m_rowLength;
	int			m_skipImages;
	int			m_skipRows;
	int			m_skipPixels;
	int			m_alignment;
	int			m_offset;
};

// TexImage3D() depth case.
class TexImageCubeArrayDepthCase : public TextureCubeArraySpecCase
{
public:
	TexImageCubeArrayDepthCase (Context&	context,
							  const char*	name,
							  const char*	desc,
							  deUint32		internalFormat,
							  int			imageSize,
							  int			numLayers)
		: TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageSize, numLayers, maxLevelCount(imageSize))
		, m_internalFormat		(internalFormat)
	{
		// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
		m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
		m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
	}

	void createTexture (void)
	{
		glu::TransferFormat	fmt			= glu::getTransferFormat(m_texFormat);
		deUint32			tex			= 0;
		tcu::TextureLevel	levelData	(glu::mapGLTransferFormat(fmt.format, fmt.dataType));

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		GLU_CHECK();

		for (int ndx = 0; ndx < m_numLevels; ndx++)
		{
			const int   levelW		= de::max(1, m_size >> ndx);
			const Vec4  gMin		= Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
			const Vec4  gMax		= Vec4(2.0f, 1.5f, -1.0f, 2.0f);

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

			glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, m_internalFormat, levelW, levelW, m_depth, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
		}
	}

	const deUint32 m_internalFormat;
};

// TexSubImage3D() depth case.
class TexSubImageCubeArrayDepthCase : public TextureCubeArraySpecCase
{
public:
	TexSubImageCubeArrayDepthCase (Context&		context,
								 const char*	name,
								 const char*	desc,
								 deUint32		internalFormat,
								 int			imageSize,
								 int			numLayers)
		: TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageSize, numLayers, maxLevelCount(imageSize))
		, m_internalFormat		(internalFormat)
	{
		// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
		m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
		m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
	}

	void createTexture (void)
	{
		glu::TransferFormat	fmt			= glu::getTransferFormat(m_texFormat);
		de::Random			rnd			(deStringHash(getName()));
		deUint32			tex			= 0;
		tcu::TextureLevel	levelData	(glu::mapGLTransferFormat(fmt.format, fmt.dataType));

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
		GLU_CHECK();

		// First specify full texture.
		for (int ndx = 0; ndx < m_numLevels; ndx++)
		{
			const int   levelW		= de::max(1, m_size >> ndx);
			const Vec4  gMin		= Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
			const Vec4  gMax		= Vec4(2.0f, 1.5f, -1.0f, 2.0f);

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

			glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, m_internalFormat, levelW, levelW, m_depth, 0, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
		}

		// Re-specify parts of each level.
		for (int ndx = 0; ndx < m_numLevels; ndx++)
		{
			const int	levelW		= de::max(1, m_size >> ndx);

			const int	w			= rnd.getInt(1, levelW);
			const int	h			= rnd.getInt(1, levelW);
			const int	d			= rnd.getInt(1, m_depth);
			const int	x			= rnd.getInt(0, levelW-w);
			const int	y			= rnd.getInt(0, levelW-h);
			const int	z			= rnd.getInt(0, m_depth-d);

			const Vec4	colorA		= Vec4(2.0f, 1.5f, -1.0f, 2.0f);
			const Vec4	colorB		= Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
			const int	cellSize	= rnd.getInt(2, 16);

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

			glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, ndx, x, y, z, w, h, d, fmt.format, fmt.dataType, levelData.getAccess().getDataPtr());
		}
	}

	const deUint32 m_internalFormat;
};

// TexImage3D() depth case with pbo.
class TexImageCubeArrayDepthBufferCase : public TextureCubeArraySpecCase
{
public:
	TexImageCubeArrayDepthBufferCase (Context&	context,
									const char*	name,
									const char*	desc,
									deUint32	internalFormat,
									int			imageSize,
									int			numLayers)
		: TextureCubeArraySpecCase(context, name, desc, glu::mapGLInternalFormat(internalFormat), imageSize, numLayers, 1)
		, m_internalFormat		(internalFormat)
	{
		// we are interested in the behavior near [-2, 2], map it to visible range [0, 1]
		m_texFormatInfo.lookupBias = Vec4(0.25f, 0.0f, 0.0f, 1.0f);
		m_texFormatInfo.lookupScale = Vec4(0.5f, 1.0f, 1.0f, 0.0f);
	}

	void createTexture (void)
	{
		glu::TransferFormat		transferFmt		= glu::getTransferFormat(m_texFormat);
		int						pixelSize		= m_texFormat.getPixelSize();
		int						rowLength		= m_size;
		int						alignment		= 4;
		int						rowPitch		= deAlign32(rowLength*pixelSize, alignment);
		int						imageHeight		= m_size;
		int						slicePitch		= imageHeight*rowPitch;
		deUint32				tex				= 0;
		deUint32				buf				= 0;
		vector<deUint8>			data;

		DE_ASSERT(m_numLevels == 1);

		// Fill data with grid.
		data.resize(slicePitch*m_depth);
		{
			const Vec4 gMin = Vec4(-1.5f, -2.0f, 1.7f, -1.5f);
			const Vec4 gMax = Vec4(2.0f, 1.5f, -1.0f, 2.0f);

			tcu::fillWithComponentGradients(tcu::PixelBufferAccess(m_texFormat, m_size, m_size, m_depth, rowPitch, slicePitch, &data[0]), gMin, gMax);
		}

		glGenBuffers(1, &buf);
		glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buf);
		glBufferData(GL_PIXEL_UNPACK_BUFFER, (int)data.size(), &data[0], GL_STATIC_DRAW);

		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT,	imageHeight);
		glPixelStorei(GL_UNPACK_ROW_LENGTH,		rowLength);
		glPixelStorei(GL_UNPACK_SKIP_IMAGES,	0);
		glPixelStorei(GL_UNPACK_SKIP_ROWS,		0);
		glPixelStorei(GL_UNPACK_SKIP_PIXELS,	0);
		glPixelStorei(GL_UNPACK_ALIGNMENT,		alignment);

		glGenTextures(1, &tex);
		glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
		glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, m_internalFormat, m_size, m_size, m_depth, 0, transferFmt.format, transferFmt.dataType, DE_NULL);
		glDeleteBuffers(1, &buf);
	}

	const deUint32 m_internalFormat;
};

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

TextureSpecificationTests::~TextureSpecificationTests (void)
{
}

void TextureSpecificationTests::init (void)
{
	struct
	{
		const char*	name;
		deUint32	internalFormat;
	} colorFormats[] =
	{
		{ "rgba32f",			GL_RGBA32F,			},
		{ "rgba32i",			GL_RGBA32I,			},
		{ "rgba32ui",			GL_RGBA32UI,		},
		{ "rgba16f",			GL_RGBA16F,			},
		{ "rgba16i",			GL_RGBA16I,			},
		{ "rgba16ui",			GL_RGBA16UI,		},
		{ "rgba8",				GL_RGBA8,			},
		{ "rgba8i",				GL_RGBA8I,			},
		{ "rgba8ui",			GL_RGBA8UI,			},
		{ "srgb8_alpha8",		GL_SRGB8_ALPHA8,	},
		{ "rgb10_a2",			GL_RGB10_A2,		},
		{ "rgb10_a2ui",			GL_RGB10_A2UI,		},
		{ "rgba4",				GL_RGBA4,			},
		{ "rgb5_a1",			GL_RGB5_A1,			},
		{ "rgba8_snorm",		GL_RGBA8_SNORM,		},
		{ "rgb8",				GL_RGB8,			},
		{ "rgb565",				GL_RGB565,			},
		{ "r11f_g11f_b10f",		GL_R11F_G11F_B10F,	},
		{ "rgb32f",				GL_RGB32F,			},
		{ "rgb32i",				GL_RGB32I,			},
		{ "rgb32ui",			GL_RGB32UI,			},
		{ "rgb16f",				GL_RGB16F,			},
		{ "rgb16i",				GL_RGB16I,			},
		{ "rgb16ui",			GL_RGB16UI,			},
		{ "rgb8_snorm",			GL_RGB8_SNORM,		},
		{ "rgb8i",				GL_RGB8I,			},
		{ "rgb8ui",				GL_RGB8UI,			},
		{ "srgb8",				GL_SRGB8,			},
		{ "rgb9_e5",			GL_RGB9_E5,			},
		{ "rg32f",				GL_RG32F,			},
		{ "rg32i",				GL_RG32I,			},
		{ "rg32ui",				GL_RG32UI,			},
		{ "rg16f",				GL_RG16F,			},
		{ "rg16i",				GL_RG16I,			},
		{ "rg16ui",				GL_RG16UI,			},
		{ "rg8",				GL_RG8,				},
		{ "rg8i",				GL_RG8I,			},
		{ "rg8ui",				GL_RG8UI,			},
		{ "rg8_snorm",			GL_RG8_SNORM,		},
		{ "r32f",				GL_R32F,			},
		{ "r32i",				GL_R32I,			},
		{ "r32ui",				GL_R32UI,			},
		{ "r16f",				GL_R16F,			},
		{ "r16i",				GL_R16I,			},
		{ "r16ui",				GL_R16UI,			},
		{ "r8",					GL_R8,				},
		{ "r8i",				GL_R8I,				},
		{ "r8ui",				GL_R8UI,			},
		{ "r8_snorm",			GL_R8_SNORM,		}
	};

	static const struct
	{
		const char*	name;
		deUint32	internalFormat;
	} depthStencilFormats[] =
	{
		// Depth and stencil formats
		{ "depth_component32f",	GL_DEPTH_COMPONENT32F	},
		{ "depth_component24",	GL_DEPTH_COMPONENT24	},
		{ "depth_component16",	GL_DEPTH_COMPONENT16	},
		{ "depth32f_stencil8",	GL_DEPTH32F_STENCIL8	},
		{ "depth24_stencil8",	GL_DEPTH24_STENCIL8		}
	};

	// Basic TexImage3D usage.
	{
		tcu::TestCaseGroup* basicTexImageGroup = new tcu::TestCaseGroup(m_testCtx, "basic_teximage3d", "Basic glTexImage3D() usage");
		addChild(basicTexImageGroup);
		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
		{
			const char*	fmtName				= colorFormats[formatNdx].name;
			deUint32	format				= colorFormats[formatNdx].internalFormat;
			const int	texCubeArraySize	= 64;
			const int	texCubeArrayLayers	= 6;

			basicTexImageGroup->addChild(new BasicTexImageCubeArrayCase	(m_context,	(string(fmtName) + "_cube_array").c_str(),	"",	format, texCubeArraySize, texCubeArrayLayers));
		}
	}

	// glTexImage3D() pbo cases.
	{
		tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_pbo", "glTexImage3D() from PBO");
		addChild(pboGroup);

		// Parameter cases
		static const struct
		{
			const char*	name;
			deUint32	format;
			int			size;
			int			depth;
			int			imageHeight;
			int			rowLength;
			int			skipImages;
			int			skipRows;
			int			skipPixels;
			int			alignment;
			int			offset;
		} parameterCases[] =
		{
			{ "rgb8_offset",		GL_RGB8,	23,	6,	0,	0,	0,	0,	0,	1,	67 },
			{ "rgb8_alignment",		GL_RGB8,	23,	6,	0,	0,	0,	0,	0,	2,	0 },
			{ "rgb8_image_height",	GL_RGB8,	23,	6,	26,	0,	0,	0,	0,	4,	0 },
			{ "rgb8_row_length",	GL_RGB8,	23,	6,	0,	27,	0,	0,	0,	4,	0 },
			{ "rgb8_skip_images",	GL_RGB8,	23,	6,	0,	0,	3,	0,	0,	4,	0 },
			{ "rgb8_skip_rows",		GL_RGB8,	23,	6,	26,	0,	0,	3,	0,	4,	0 },
			{ "rgb8_skip_pixels",	GL_RGB8,	23,	6,	0,	25,	0,	0,	2,	4,	0 }
		};

		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
		{
			const string	fmtName				= colorFormats[formatNdx].name;
			const deUint32	format				= colorFormats[formatNdx].internalFormat;
			const int		texCubeArraySize	= 20;
			const int		texCubeDepth		= 6;

			pboGroup->addChild(new TexImageCubeArrayBufferCase	(m_context, (fmtName + "_cube_array").c_str(),	"", format, texCubeArraySize, texCubeDepth, 0, 0, 0, 0, 0, 4, 0));
		}

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(parameterCases); ndx++)
		{
			pboGroup->addChild(new TexImageCubeArrayBufferCase(m_context, (string(parameterCases[ndx].name) + "_cube_array").c_str(), "",
														parameterCases[ndx].format,
														parameterCases[ndx].size,
														parameterCases[ndx].depth,
														parameterCases[ndx].imageHeight,
														parameterCases[ndx].rowLength,
														parameterCases[ndx].skipImages,
														parameterCases[ndx].skipRows,
														parameterCases[ndx].skipPixels,
														parameterCases[ndx].alignment,
														parameterCases[ndx].offset));
		}
	}

	// glTexImage3D() depth cases.
	{
		tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_depth", "glTexImage3D() with depth or depth/stencil format");
		addChild(shadow3dGroup);

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
		{
			const int	texCubeArraySize	= 64;
			const int	texCubeArrayDepth	= 6;

			shadow3dGroup->addChild(new TexImageCubeArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_cube_array").c_str(), "", depthStencilFormats[ndx].internalFormat, texCubeArraySize, texCubeArrayDepth));
		}
	}

	// glTexImage3D() depth cases with pbo.
	{
		tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "teximage3d_depth_pbo", "glTexImage3D() with depth or depth/stencil format with pbo");
		addChild(shadow3dGroup);

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
		{
			const int	texCubeArraySize	= 64;
			const int	texCubeArrayDepth	= 6;

			shadow3dGroup->addChild(new TexImageCubeArrayDepthBufferCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_cube_array").c_str(), "", depthStencilFormats[ndx].internalFormat, texCubeArraySize, texCubeArrayDepth));
		}
	}

	// glTexSubImage3D() PBO cases.
	{
		tcu::TestCaseGroup* pboGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_pbo", "glTexSubImage3D() pixel buffer object tests");
		addChild(pboGroup);

		static const struct
		{
			const char*	name;
			deUint32	format;
			int			size;
			int			depth;
			int			subX;
			int			subY;
			int			subZ;
			int			subW;
			int			subH;
			int			subD;
			int			imageHeight;
			int			rowLength;
			int			skipImages;
			int			skipRows;
			int			skipPixels;
			int			alignment;
			int			offset;
		} paramCases[] =
		{
			{ "rgb8_offset",		GL_RGB8,	26, 12,	1,	2,	1,	23,	19,	8,	0,	0,	0,	0,	0,	4,	67 },
			{ "rgb8_image_height",	GL_RGB8,	26, 12,	1,	2,	1,	23,	19,	8,	26,	0,	0,	0,	0,	4,	0 },
			{ "rgb8_row_length",	GL_RGB8,	26, 12,	1,	2,	1,	23,	19,	8,	0,	27,	0,	0,	0,	4,	0 },
			{ "rgb8_skip_images",	GL_RGB8,	26, 12,	1,	2,	1,	23,	19,	8,	0,	0,	3,	0,	0,	4,	0 },
			{ "rgb8_skip_rows",		GL_RGB8,	26, 12,	1,	2,	1,	23,	19,	8,	22,	0,	0,	3,	0,	4,	0 },
			{ "rgb8_skip_pixels",	GL_RGB8,	26, 12,	1,	2,	1,	23,	19,	8,	0,	25,	0,	0,	2,	4,	0 }
		};

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
		{
			pboGroup->addChild(new TexSubImageCubeArrayBufferCase(m_context, (std::string(colorFormats[ndx].name) + "_cube_array").c_str(), "",
														   colorFormats[ndx].internalFormat,
														   26,	// Size
														   12,	// Depth
														   1,	// Sub X
														   2,	// Sub Y
														   0,	// Sub Z
														   23,	// Sub W
														   19,	// Sub H
														   8,	// Sub D
														   0,	// Image height
														   0,	// Row length
														   0,	// Skip images
														   0,	// Skip rows
														   0,	// Skip pixels
														   4,	// Alignment
														   0	/* offset */));
		}

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(paramCases); ndx++)
		{
			pboGroup->addChild(new TexSubImageCubeArrayBufferCase(m_context, (std::string(paramCases[ndx].name) + "_cube_array").c_str(), "",
														   paramCases[ndx].format,
														   paramCases[ndx].size,
														   paramCases[ndx].depth,
														   paramCases[ndx].subX,
														   paramCases[ndx].subY,
														   paramCases[ndx].subZ,
														   paramCases[ndx].subW,
														   paramCases[ndx].subH,
														   paramCases[ndx].subD,
														   paramCases[ndx].imageHeight,
														   paramCases[ndx].rowLength,
														   paramCases[ndx].skipImages,
														   paramCases[ndx].skipRows,
														   paramCases[ndx].skipPixels,
														   paramCases[ndx].alignment,
														   paramCases[ndx].offset));
		}
	}

	// glTexSubImage3D() depth cases.
	{
		tcu::TestCaseGroup* shadow3dGroup = new tcu::TestCaseGroup(m_testCtx, "texsubimage3d_depth", "glTexSubImage3D() with depth or depth/stencil format");
		addChild(shadow3dGroup);

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++)
		{
			const int	texCubeArraySize	= 57;
			const int	texCubeArrayLayers	= 6;

			shadow3dGroup->addChild(new TexSubImageCubeArrayDepthCase(m_context, (std::string(depthStencilFormats[ndx].name) + "_cube_array").c_str(), "", depthStencilFormats[ndx].internalFormat, texCubeArraySize, texCubeArrayLayers));
		}
	}

	// glTexStorage3D() cases.
	{
		tcu::TestCaseGroup* texStorageGroup = new tcu::TestCaseGroup(m_testCtx, "texstorage3d", "Basic glTexStorage3D() usage");
		addChild(texStorageGroup);

		// All formats.
		tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "glTexStorage3D() with all formats");
		texStorageGroup->addChild(formatGroup);

		// Color formats.
		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(colorFormats); formatNdx++)
		{
			const char*	fmtName				= colorFormats[formatNdx].name;
			deUint32	internalFormat		= colorFormats[formatNdx].internalFormat;
			const int	texCubeArraySize	= 57;
			const int	texCubeArrayLayers	= 6;
			int			texCubeArrayLevels	= maxLevelCount(texCubeArraySize);

			formatGroup->addChild(new BasicTexStorageCubeArrayCase	(m_context, (string(fmtName) + "_cube_array").c_str(),	"", internalFormat, texCubeArraySize, texCubeArrayLayers, texCubeArrayLevels));
		}

		// Depth/stencil formats (only 2D texture array is supported).
		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); formatNdx++)
		{
			const char*	fmtName				= depthStencilFormats[formatNdx].name;
			deUint32	internalFormat		= depthStencilFormats[formatNdx].internalFormat;
			const int	texCubeArraySize	= 57;
			const int	texCubeArrayLayers	= 6;
			int			texCubeArrayLevels	= maxLevelCount(texCubeArraySize);

			formatGroup->addChild(new BasicTexStorageCubeArrayCase	(m_context, (string(fmtName) + "_cube_array").c_str(),	"", internalFormat, texCubeArraySize, texCubeArrayLayers, texCubeArrayLevels));
		}

		// Sizes.
		static const struct
		{
			int				size;
			int				layers;
			int				levels;
		} texCubeArraySizes[] =
		{
			//	Sz	La	Le
			{	1,	6,	1 },
			{	2,	6,	2 },
			{	32,	6,	3 },
			{	64,	6,	4 },
			{	57,	12,	1 },
			{	57,	12,	2 },
			{	57,	12,	6 }
		};

		tcu::TestCaseGroup* sizeGroup = new tcu::TestCaseGroup(m_testCtx, "size", "glTexStorage3D() with various sizes");
		texStorageGroup->addChild(sizeGroup);

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(texCubeArraySizes); ndx++)
		{
			const deUint32		format		= GL_RGBA8;
			int					size		= texCubeArraySizes[ndx].size;
			int					layers		= texCubeArraySizes[ndx].layers;
			int					levels		= texCubeArraySizes[ndx].levels;
			string				name		= string("cube_array_") + de::toString(size) + "x" + de::toString(size) + "x" + de::toString(layers) + "_" + de::toString(levels) + "_levels";

			sizeGroup->addChild(new BasicTexStorageCubeArrayCase(m_context, name.c_str(), "", format, size, layers, levels));
		}
	}
}

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