/*-------------------------------------------------------------------------
 * 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;

//! 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
