/*-------------------------------------------------------------------------
 * 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 wrap mode tests.
 *//*--------------------------------------------------------------------*/

#include "es3fTextureWrapTests.hpp"
#include "glsTextureTestUtil.hpp"
#include "gluTexture.hpp"
#include "gluStrUtil.hpp"
#include "gluTextureUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "tcuTestLog.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuCompressedTexture.hpp"
#include "tcuVectorUtil.hpp"
#include "tcuTexLookupVerifier.hpp"
#include "deRandom.hpp"
#include "deStringUtil.hpp"
#include "deMemory.h"

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

namespace deqp
{
namespace gles3
{
namespace Functional
{

using tcu::TestLog;
using tcu::CompressedTexture;
using tcu::CompressedTexFormat;
using std::vector;
using std::string;
using tcu::Sampler;
using namespace glu;
using namespace gls::TextureTestUtil;
using namespace glu::TextureTestUtil;

//! Checks whether any ASTC version (LDR, HDR, full) is supported.
static inline bool isASTCSupported (const glu::ContextInfo& contextInfo)
{
	const vector<string>& extensions = contextInfo.getExtensions();

	for (int extNdx = 0; extNdx < (int)extensions.size(); extNdx++)
	{
		const string& ext = extensions[extNdx];

		if (ext == "GL_KHR_texture_compression_astc_ldr" ||
			ext == "GL_KHR_texture_compression_astc_hdr" ||
			ext == "GL_OES_texture_compression_astc")
			return true;
	}

	return false;
}

enum
{
	VIEWPORT_WIDTH		= 256,
	VIEWPORT_HEIGHT		= 256
};

class TextureWrapCase : public tcu::TestCase
{
public:
									TextureWrapCase			(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, deUint32 format, deUint32 dataType, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, int width, int height);
									TextureWrapCase			(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, const std::vector<std::string>& filenames);
									TextureWrapCase			(tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, CompressedTexFormat compressedFormat, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, int width, int height);
									~TextureWrapCase		(void);

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

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

	struct Case
	{
		tcu::Vec2 bottomLeft;
		tcu::Vec2 topRight;

		Case (void) {}
		Case (const tcu::Vec2& bl, const tcu::Vec2& tr) : bottomLeft(bl), topRight(tr) {}
	};

	glu::RenderContext&				m_renderCtx;
	const glu::ContextInfo&			m_renderCtxInfo;

	const deUint32					m_format;
	const deUint32					m_dataType;
	const CompressedTexFormat		m_compressedFormat;
	const deUint32					m_wrapS;
	const deUint32					m_wrapT;
	const deUint32					m_minFilter;
	const deUint32					m_magFilter;

	int								m_width;
	int								m_height;
	const std::vector<std::string>	m_filenames;

	vector<Case>					m_cases;
	int								m_caseNdx;

	glu::Texture2D*					m_texture;
	TextureRenderer					m_renderer;
};

TextureWrapCase::TextureWrapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, deUint32 format, deUint32 dataType, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, int width, int height)
	: TestCase				(testCtx, name, description)
	, m_renderCtx			(renderCtx)
	, m_renderCtxInfo		(ctxInfo)
	, m_format				(format)
	, m_dataType			(dataType)
	, m_compressedFormat	(tcu::COMPRESSEDTEXFORMAT_LAST)
	, m_wrapS				(wrapS)
	, m_wrapT				(wrapT)
	, m_minFilter			(minFilter)
	, m_magFilter			(magFilter)
	, m_width				(width)
	, m_height				(height)
	, m_caseNdx				(0)
	, m_texture				(DE_NULL)
	, m_renderer			(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_MEDIUMP)
{
}

TextureWrapCase::TextureWrapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, const std::vector<std::string>& filenames)
	: TestCase				(testCtx, name, description)
	, m_renderCtx			(renderCtx)
	, m_renderCtxInfo		(ctxInfo)
	, m_format				(GL_NONE)
	, m_dataType			(GL_NONE)
	, m_compressedFormat	(tcu::COMPRESSEDTEXFORMAT_LAST)
	, m_wrapS				(wrapS)
	, m_wrapT				(wrapT)
	, m_minFilter			(minFilter)
	, m_magFilter			(magFilter)
	, m_width				(0)
	, m_height				(0)
	, m_filenames			(filenames)
	, m_caseNdx				(0)
	, m_texture				(DE_NULL)
	, m_renderer			(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_MEDIUMP)
{
}

TextureWrapCase::TextureWrapCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const glu::ContextInfo& ctxInfo, const char* name, const char* description, CompressedTexFormat compressedFormat, deUint32 wrapS, deUint32 wrapT, deUint32 minFilter, deUint32 magFilter, int width, int height)
	: TestCase				(testCtx, name, description)
	, m_renderCtx			(renderCtx)
	, m_renderCtxInfo		(ctxInfo)
	, m_format				(GL_NONE)
	, m_dataType			(GL_NONE)
	, m_compressedFormat	(compressedFormat)
	, m_wrapS				(wrapS)
	, m_wrapT				(wrapT)
	, m_minFilter			(minFilter)
	, m_magFilter			(magFilter)
	, m_width				(width)
	, m_height				(height)
	, m_caseNdx				(0)
	, m_texture				(DE_NULL)
	, m_renderer			(renderCtx, testCtx.getLog(), glu::GLSL_VERSION_300_ES, glu::PRECISION_MEDIUMP)
{
}


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

void TextureWrapCase::init (void)
{
	// Load or generate texture.

	if (!m_filenames.empty())
	{
		// Load compressed texture from file.

		DE_ASSERT(m_width == 0 && m_height == 0 && m_format == GL_NONE && m_dataType == GL_NONE);

		m_texture	= glu::Texture2D::create(m_renderCtx, m_renderCtxInfo, m_testCtx.getArchive(), (int)m_filenames.size(), m_filenames);
		m_width		= m_texture->getRefTexture().getWidth();
		m_height	= m_texture->getRefTexture().getHeight();
	}
	else if (m_compressedFormat != tcu::COMPRESSEDTEXFORMAT_LAST)
	{
		// Generate compressed texture.

		DE_ASSERT(m_format == GL_NONE && m_dataType == GL_NONE);

		if (tcu::isEtcFormat(m_compressedFormat))
		{
			// Create ETC texture. Any content is valid.

			tcu::CompressedTexture	compressedTexture	(m_compressedFormat, m_width, m_height);
			const int				dataSize			= compressedTexture.getDataSize();
			deUint8* const			data				= (deUint8*)compressedTexture.getData();
			de::Random				rnd					(deStringHash(getName()));

			for (int i = 0; i < dataSize; i++)
				data[i] = rnd.getUint32() & 0xff;

			m_texture = new glu::Texture2D(m_renderCtx, m_renderCtxInfo, 1, &compressedTexture);
		}
		else if (tcu::isAstcFormat(m_compressedFormat))
		{
			// Create ASTC texture by picking from a set of pre-generated blocks.

			static const int		BLOCK_SIZE				= 16;
			static const deUint8	blocks[][BLOCK_SIZE]	=
			{
				// \note All of the following blocks are valid in LDR mode.
				{ 252,	253,	255,	255,	255,	255,	255,	255,	8,		71,		90,		78,		22,		17,		26,		66,		},
				{ 252,	253,	255,	255,	255,	255,	255,	255,	220,	74,		139,	235,	249,	6,		145,	125		},
				{ 252,	253,	255,	255,	255,	255,	255,	255,	223,	251,	28,		206,	54,		251,	160,	174		},
				{ 252,	253,	255,	255,	255,	255,	255,	255,	39,		4,		153,	219,	180,	61,		51,		37		},
				{ 67,	2,		0,		254,	1,		0,		64,		215,	83,		211,	159,	105,	41,		140,	50,		2		},
				{ 67,	130,	0,		170,	84,		255,	65,		215,	83,		211,	159,	105,	41,		140,	50,		2		},
				{ 67,	2,		129,	38,		51,		229,	95,		215,	83,		211,	159,	105,	41,		140,	50,		2		},
				{ 67,	130,	193,	56,		213,	144,	95,		215,	83,		211,	159,	105,	41,		140,	50,		2		}
			};

			if (!isASTCSupported(m_renderCtxInfo)) // \note Any level of ASTC support is enough, since we're only using LDR blocks.
				throw tcu::NotSupportedError("ASTC not supported");

			tcu::CompressedTexture	compressedTexture	(m_compressedFormat, m_width, m_height);
			const int				dataSize			= compressedTexture.getDataSize();
			deUint8* const			data				= (deUint8*)compressedTexture.getData();
			de::Random				rnd					(deStringHash(getName()));
			DE_ASSERT(dataSize % BLOCK_SIZE == 0);

			for (int i = 0; i < dataSize/BLOCK_SIZE; i++)
				deMemcpy(&data[i*BLOCK_SIZE], &blocks[rnd.getInt(0, DE_LENGTH_OF_ARRAY(blocks)-1)][0], BLOCK_SIZE);

			// \note All blocks are valid LDR blocks so ASTCMODE_* doesn't change anything
			m_texture = new glu::Texture2D(m_renderCtx, m_renderCtxInfo, 1, &compressedTexture, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
		}
		else
			DE_ASSERT(false);
	}
	else
	{
		m_texture = new Texture2D(m_renderCtx, m_format, m_dataType, m_width, m_height);

		// Fill level 0.
		m_texture->getRefTexture().allocLevel(0);
		tcu::fillWithComponentGradients(m_texture->getRefTexture().getLevel(0), tcu::Vec4(-0.5f, -0.5f, -0.5f, 2.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 0.0f));

		m_texture->upload();
	}

	// Sub-cases.

	m_cases.push_back(Case(tcu::Vec2(-1.5f, -3.0f), tcu::Vec2(1.5f, 2.5f)));
	m_cases.push_back(Case(tcu::Vec2(-0.5f, 0.75f), tcu::Vec2(0.25f, 1.25f)));
	DE_ASSERT(m_caseNdx == 0);

	// Initialize to success, set to failure later if needed.

	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
}

void TextureWrapCase::deinit (void)
{
	delete m_texture;
	m_texture = DE_NULL;

	m_renderer.clear();
}

TextureWrapCase::IterateResult TextureWrapCase::iterate (void)
{
	const glw::Functions&			gl								= m_renderCtx.getFunctions();
	TestLog&						log								= m_testCtx.getLog();
	const RandomViewport			viewport						(m_renderCtx.getRenderTarget(), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, deStringHash(getName()) + m_caseNdx);
	tcu::Surface					renderedFrame					(viewport.width, viewport.height);
	ReferenceParams					refParams						(TEXTURETYPE_2D);
	const tcu::TextureFormat		texFormat						= m_texture->getRefTexture().getFormat();
	vector<float>					texCoord;
	const tcu::TextureFormatInfo	texFormatInfo					= tcu::getTextureFormatInfo(texFormat);
	// \note For non-sRGB ASTC formats, the values are fp16 in range [0..1], not the range assumed given by tcu::getTextureFormatInfo().
	const bool						useDefaultColorScaleAndBias		= !tcu::isAstcFormat(m_compressedFormat) || tcu::isAstcSRGBFormat(m_compressedFormat);

	// Bind to unit 0.
	gl.activeTexture(GL_TEXTURE0);
	gl.bindTexture(GL_TEXTURE_2D, m_texture->getGLTexture());

	// Setup filtering and wrap modes.
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,		m_wrapS);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,		m_wrapT);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,	m_minFilter);
	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,	m_magFilter);

	GLU_EXPECT_NO_ERROR(gl.getError(), "Set texturing state");

	// Parameters for reference images.
	refParams.sampler		= mapGLSampler(m_wrapS, m_wrapT, m_minFilter, m_magFilter);
	refParams.lodMode		= LODMODE_EXACT;
	refParams.samplerType	= getSamplerType(m_texture->getRefTexture().getFormat());
	refParams.colorScale	= useDefaultColorScaleAndBias ? texFormatInfo.lookupScale	: tcu::Vec4(1.0f);
	refParams.colorBias		= useDefaultColorScaleAndBias ? texFormatInfo.lookupBias	: tcu::Vec4(0.0f);

	gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
	computeQuadTexCoord2D(texCoord, m_cases[m_caseNdx].bottomLeft, m_cases[m_caseNdx].topRight);
	m_renderer.renderQuad(0, &texCoord[0], refParams);
	glu::readPixels(m_renderCtx, viewport.x, viewport.y, renderedFrame.getAccess());

	{
		const tcu::ScopedLogSection		section			(log, string("Test") + de::toString(m_caseNdx), string("Test ") + de::toString(m_caseNdx));
		const bool						isNearestOnly	= m_minFilter == GL_NEAREST && m_magFilter == GL_NEAREST;
		const bool						isSRGB			= tcu::isSRGB(texFormat);
		const tcu::PixelFormat			pixelFormat		= m_renderCtx.getRenderTarget().getPixelFormat();
		const tcu::IVec4				colorBits		= tcu::max(getBitsVec(pixelFormat) - (isNearestOnly && !isSRGB ? 1 : 2), tcu::IVec4(0));
		tcu::LodPrecision				lodPrecision;
		tcu::LookupPrecision			lookupPrecision;

		lodPrecision.derivateBits		= 18;
		lodPrecision.lodBits			= 5;
		lookupPrecision.colorThreshold	= tcu::computeFixedPointThreshold(colorBits) / refParams.colorScale;
		lookupPrecision.coordBits		= tcu::IVec3(20,20,0);
		lookupPrecision.uvwBits			= tcu::IVec3(5,5,0);
		lookupPrecision.colorMask		= getCompareMask(pixelFormat);

		log << TestLog::Message << "Note: lookup coordinates: bottom-left " << m_cases[m_caseNdx].bottomLeft << ", top-right " << m_cases[m_caseNdx].topRight << TestLog::EndMessage;

		const bool isOk = verifyTextureResult(m_testCtx, renderedFrame.getAccess(), m_texture->getRefTexture(),
											  &texCoord[0], refParams, lookupPrecision, lodPrecision, pixelFormat);

		if (!isOk)
			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
	}

	m_caseNdx++;
	return m_caseNdx < (int)m_cases.size() ? CONTINUE : STOP;
}

TextureWrapTests::TextureWrapTests (Context& context)
	: TestCaseGroup(context, "wrap", "Wrap Mode Tests")
{
}

TextureWrapTests::~TextureWrapTests (void)
{
}

void TextureWrapTests::init (void)
{
	static const struct
	{
		const char*		name;
		deUint32		mode;
	} wrapModes[] =
	{
		{ "clamp",		GL_CLAMP_TO_EDGE },
		{ "repeat",		GL_REPEAT },
		{ "mirror",		GL_MIRRORED_REPEAT }
	};

	static const struct
	{
		const char*		name;
		deUint32		mode;
	} filteringModes[] =
	{
		{ "nearest",	GL_NEAREST },
		{ "linear",		GL_LINEAR }
	};

#define FOR_EACH(ITERATOR, ARRAY, BODY)	\
	for (int ITERATOR = 0; ITERATOR < DE_LENGTH_OF_ARRAY(ARRAY); ITERATOR++)	\
		BODY

	// RGBA8 cases.
	{
		static const struct
		{
			const char*		name;
			int				width;
			int				height;
		} rgba8Sizes[] =
		{
			{ "pot",		64, 128 },
			{ "npot",		63, 112 }
		};

		{
			TestCaseGroup* const rgba8Group = new TestCaseGroup(m_context, "rgba8", "");
			addChild(rgba8Group);

			FOR_EACH(size,		rgba8Sizes,
			FOR_EACH(wrapS,		wrapModes,
			FOR_EACH(wrapT,		wrapModes,
			FOR_EACH(filter,	filteringModes,
				{
					const string name = string("") + wrapModes[wrapS].name + "_" + wrapModes[wrapT].name + "_" + filteringModes[filter].name + "_" + rgba8Sizes[size].name;
					rgba8Group->addChild(new TextureWrapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
															 GL_RGBA, GL_UNSIGNED_BYTE,
															 wrapModes[wrapS].mode,
															 wrapModes[wrapT].mode,
															 filteringModes[filter].mode, filteringModes[filter].mode,
															 rgba8Sizes[size].width, rgba8Sizes[size].height));

				}))));
		}
	}

	// ETC1 cases.
	{
		TestCaseGroup* const etc1Group = new TestCaseGroup(m_context, "etc1", "");
		addChild(etc1Group);

		// Power-of-two ETC1 texture
		std::vector<std::string> potFilenames;
		potFilenames.push_back("data/etc1/photo_helsinki_mip_0.pkm");

		FOR_EACH(wrapS,		wrapModes,
		FOR_EACH(wrapT,		wrapModes,
		FOR_EACH(filter,	filteringModes,
			{
				const string name = string("") + wrapModes[wrapS].name + "_" + wrapModes[wrapT].name + "_" + filteringModes[filter].name + "_pot";
				etc1Group->addChild(new TextureWrapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
														wrapModes[wrapS].mode,
														wrapModes[wrapT].mode,
														filteringModes[filter].mode, filteringModes[filter].mode,
														potFilenames));

			})));

		std::vector<std::string> npotFilenames;
		npotFilenames.push_back("data/etc1/photo_helsinki_113x89.pkm");

		// NPOT ETC1 texture
		FOR_EACH(wrapS,		wrapModes,
		FOR_EACH(wrapT,		wrapModes,
		FOR_EACH(filter,	filteringModes,
			{
				const string name = string("") + wrapModes[wrapS].name + "_" + wrapModes[wrapT].name + "_" + filteringModes[filter].name + "_npot";
				etc1Group->addChild(new TextureWrapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
														wrapModes[wrapS].mode,
														wrapModes[wrapT].mode,
														filteringModes[filter].mode, filteringModes[filter].mode,
														npotFilenames));
			})));
	}

	// ETC-2 (and EAC) cases.
	{
		static const struct
		{
			const char*			name;
			CompressedTexFormat	format;
		} etc2Formats[] =
		{
			{ "eac_r11",							tcu::COMPRESSEDTEXFORMAT_EAC_R11,							},
			{ "eac_signed_r11",						tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11,					},
			{ "eac_rg11",							tcu::COMPRESSEDTEXFORMAT_EAC_RG11,							},
			{ "eac_signed_rg11",					tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11,					},
			{ "etc2_rgb8",							tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8,							},
			{ "etc2_srgb8",							tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8,						},
			{ "etc2_rgb8_punchthrough_alpha1",		tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1,		},
			{ "etc2_srgb8_punchthrough_alpha1",		tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1,	},
			{ "etc2_eac_rgba8",						tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8,					},
			{ "etc2_eac_srgb8_alpha8",				tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8,				}
		};

		static const struct
		{
			const char*		name;
			int				width;
			int				height;
		} etc2Sizes[] =
		{
			{ "pot",	64,		128	},
			{ "npot",	123,	107	}
		};

		for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(etc2Formats); formatNdx++)
		{
			TestCaseGroup* const formatGroup = new TestCaseGroup(m_context, etc2Formats[formatNdx].name, "");
			addChild(formatGroup);

			FOR_EACH(size,		etc2Sizes,
			FOR_EACH(wrapS,		wrapModes,
			FOR_EACH(wrapT,		wrapModes,
			FOR_EACH(filter,	filteringModes,
				{
					const string name = string("") + wrapModes[wrapS].name + "_" + wrapModes[wrapT].name + "_" + filteringModes[filter].name + "_" + etc2Sizes[size].name;
					formatGroup->addChild(new TextureWrapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
															  etc2Formats[formatNdx].format,
															  wrapModes[wrapS].mode,
															  wrapModes[wrapT].mode,
															  filteringModes[filter].mode, filteringModes[filter].mode,
															  etc2Sizes[size].width, etc2Sizes[size].height));
				}))));
		}
	}

	// ASTC cases.
	{
		for (int formatI = 0; formatI < tcu::COMPRESSEDTEXFORMAT_LAST; formatI++)
		{
			const CompressedTexFormat format = (CompressedTexFormat)formatI;

			if (!tcu::isAstcFormat(format))
				continue;

			{
				const tcu::IVec3		blockSize		= tcu::getBlockPixelSize(format);
				const string			formatName		= "astc_" + de::toString(blockSize.x()) + "x" + de::toString(blockSize.y()) + (tcu::isAstcSRGBFormat(format) ? "_srgb" : "");
				TestCaseGroup* const	formatGroup		= new TestCaseGroup(m_context, formatName.c_str(), "");
				addChild(formatGroup);

				DE_ASSERT(blockSize.z() == 1);

				// \note This array is NOT static.
				const struct
				{
					const char*		name;
					int				width;
					int				height;
				} formatSizes[] =
				{
					{ "divisible",		blockSize.x()*10,		blockSize.y()*10	},
					{ "not_divisible",	blockSize.x()*10+1,		blockSize.y()*10+1	},
				};

				FOR_EACH(size,		formatSizes,
				FOR_EACH(wrapS,		wrapModes,
				FOR_EACH(wrapT,		wrapModes,
				FOR_EACH(filter,	filteringModes,
					{
						string name = string("") + wrapModes[wrapS].name + "_" + wrapModes[wrapT].name + "_" + filteringModes[filter].name + "_" + formatSizes[size].name;
						formatGroup->addChild(new TextureWrapCase(m_testCtx, m_context.getRenderContext(), m_context.getContextInfo(), name.c_str(), "",
																  format,
																  wrapModes[wrapS].mode,
																  wrapModes[wrapT].mode,
																  filteringModes[filter].mode, filteringModes[filter].mode,
																  formatSizes[size].width, formatSizes[size].height));
					}))));
			}
		}
	}
}

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