/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 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 level state query tests
 *//*--------------------------------------------------------------------*/

#include "es31fTextureLevelStateQueryTests.hpp"
#include "glsStateQueryUtil.hpp"
#include "tcuTestLog.hpp"
#include "gluRenderContext.hpp"
#include "gluCallLogWrapper.hpp"
#include "gluTextureUtil.hpp"
#include "gluStrUtil.hpp"
#include "gluContextInfo.hpp"
#include "glwFunctions.hpp"
#include "glwEnums.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuFormatUtil.hpp"
#include "deStringUtil.hpp"
#include "deUniquePtr.hpp"

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace
{

using namespace gls::StateQueryUtil;


static bool textureTypeHasDepth (glw::GLenum textureBindTarget)
{
	switch (textureBindTarget)
	{
		case GL_TEXTURE_2D:						return false;
		case GL_TEXTURE_3D:						return true;
		case GL_TEXTURE_2D_ARRAY:				return true;
		case GL_TEXTURE_CUBE_MAP:				return false;
		case GL_TEXTURE_2D_MULTISAMPLE:			return false;
		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:	return true;
		case GL_TEXTURE_BUFFER:					return false;
		case GL_TEXTURE_CUBE_MAP_ARRAY:			return true;
		default:
			DE_ASSERT(DE_FALSE);
			return false;
	}
}

static bool textureTypeHasHeight (glw::GLenum textureBindTarget)
{
	switch (textureBindTarget)
	{
		case GL_TEXTURE_2D:						return true;
		case GL_TEXTURE_3D:						return true;
		case GL_TEXTURE_2D_ARRAY:				return true;
		case GL_TEXTURE_CUBE_MAP:				return true;
		case GL_TEXTURE_2D_MULTISAMPLE:			return true;
		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:	return true;
		case GL_TEXTURE_BUFFER:					return false;
		case GL_TEXTURE_CUBE_MAP_ARRAY:			return true;
		default:
			DE_ASSERT(DE_FALSE);
			return false;
	}
}

static const char* getTextureTargetExtension (glw::GLenum target)
{
	switch (target)
	{
		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:	return "GL_OES_texture_storage_multisample_2d_array";
		case GL_TEXTURE_BUFFER:					return "GL_EXT_texture_buffer";
		case GL_TEXTURE_CUBE_MAP_ARRAY:			return "GL_EXT_texture_cube_map_array";
		default:
			DE_ASSERT(DE_FALSE);
			return DE_NULL;
	}
}

static bool isCoreTextureTarget (glw::GLenum target, const glu::ContextType& contextType)
{
	switch (target)
	{
		case GL_TEXTURE_2D:
		case GL_TEXTURE_3D:
		case GL_TEXTURE_2D_ARRAY:
		case GL_TEXTURE_CUBE_MAP:
		case GL_TEXTURE_2D_MULTISAMPLE:
			return true;

		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
		case GL_TEXTURE_BUFFER:
		case GL_TEXTURE_CUBE_MAP_ARRAY:
			return glu::contextSupports(contextType, glu::ApiType::es(3, 2)) ||
				   glu::contextSupports(contextType, glu::ApiType::core(4, 5));

		default:
			return false;
	}
}

struct TextureGenerationSpec
{
	struct TextureLevelSpec
	{
		int			width;
		int			height;
		int			depth;
		int			level;
		glw::GLenum internalFormat;
		bool		compressed;

		TextureLevelSpec (void)
			: width				(0)
			, height			(0)
			, depth				(0)
			, level				(0)
			, internalFormat	(GL_RGBA)
			, compressed		(false)
		{
		}
	};

	glw::GLenum						bindTarget;
	glw::GLenum						queryTarget;
	bool							immutable;
	bool							fixedSamplePos;	// !< fixed sample pos argument for multisample textures
	int								sampleCount;
	int								texBufferDataOffset;
	int								texBufferDataSize;
	bool							bindWholeArray;
	std::vector<TextureLevelSpec>	levels;
	std::string						description;

	TextureGenerationSpec (void)
		: bindTarget			(0)
		, queryTarget			(0)
		, immutable				(true)
		, fixedSamplePos		(true)
		, sampleCount			(0)
		, texBufferDataOffset	(0)
		, texBufferDataSize		(256)
		, bindWholeArray		(false)
	{
	}
};
struct IntegerPrinter
{
	static std::string	getIntegerName	(int v)		{ return de::toString(v); }
	static std::string	getFloatName	(float v)	{ return de::toString(v); }
};

struct PixelFormatPrinter
{
	static std::string	getIntegerName	(int v)		{ return de::toString(glu::getTextureFormatStr(v));		}
	static std::string	getFloatName	(float v)	{ return de::toString(glu::getTextureFormatStr((int)v));	}
};

template <typename Printer>
static bool verifyTextureLevelParameterEqualWithPrinter (glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, int refValue, QueryType type)
{
	QueriedState			state;
	tcu::ResultCollector	result	(gl.getLog(), " // ERROR: ");

	gl.getLog() << tcu::TestLog::Message << "Verifying " << glu::getTextureLevelParameterStr(pname) << ", expecting " << Printer::getIntegerName(refValue) << tcu::TestLog::EndMessage;
	queryTextureLevelState(result, gl, type, target, level, pname, state);

	if (state.isUndefined())
		return false;

	verifyInteger(result, state, refValue);

	return result.getResult() == QP_TEST_RESULT_PASS;
}

static bool verifyTextureLevelParameterEqual (glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, int refValue, QueryType type)
{
	return verifyTextureLevelParameterEqualWithPrinter<IntegerPrinter>(gl, target, level, pname, refValue, type);
}

static bool verifyTextureLevelParameterInternalFormatEqual (glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, int refValue, QueryType type)
{
	return verifyTextureLevelParameterEqualWithPrinter<PixelFormatPrinter>(gl, target, level, pname, refValue, type);
}

static bool verifyTextureLevelParameterGreaterOrEqual (glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, int refValue, QueryType type)
{
	QueriedState			state;
	tcu::ResultCollector	result	(gl.getLog(), " // ERROR: ");

	gl.getLog() << tcu::TestLog::Message << "Verifying " << glu::getTextureLevelParameterStr(pname) << ", expecting " << refValue << " or greater" << tcu::TestLog::EndMessage;
	queryTextureLevelState(result, gl, type, target, level, pname, state);

	if (state.isUndefined())
		return false;

	verifyIntegerMin(result, state, refValue);

	return result.getResult() == QP_TEST_RESULT_PASS;
}

static bool verifyTextureLevelParameterInternalFormatAnyOf (glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, const int* refValues, int numRefValues, QueryType type)
{
	QueriedState			state;
	tcu::ResultCollector	result	(gl.getLog(), " // ERROR: ");

	// Log what we try to do
	{
		tcu::MessageBuilder msg(&gl.getLog());

		msg << "Verifying " << glu::getTextureLevelParameterStr(pname) << ", expecting any of {";
		for (int ndx = 0; ndx < numRefValues; ++ndx)
		{
			if (ndx != 0)
				msg << ", ";
			msg << glu::getTextureFormatStr(refValues[ndx]);
		}
		msg << "}";
		msg << tcu::TestLog::EndMessage;
	}

	queryTextureLevelState(result, gl, type, target, level, pname, state);
	if (state.isUndefined())
		return false;

	// verify
	switch (state.getType())
	{
		case DATATYPE_INTEGER:
		{
			for (int ndx = 0; ndx < numRefValues; ++ndx)
				if (state.getIntAccess() == refValues[ndx])
					return true;

			gl.getLog() << tcu::TestLog::Message << "Error: got " << state.getIntAccess() << ", (" << glu::getTextureFormatStr(state.getIntAccess()) << ")" << tcu::TestLog::EndMessage;
			return false;
		}
		case DATATYPE_FLOAT:
		{
			for (int ndx = 0; ndx < numRefValues; ++ndx)
				if (state.getFloatAccess() == (float)refValues[ndx])
					return true;

			gl.getLog() << tcu::TestLog::Message << "Error: got " << state.getFloatAccess() << ", (" << glu::getTextureFormatStr((int)state.getFloatAccess()) << ")" << tcu::TestLog::EndMessage;
			return false;
		}
		default:
			DE_ASSERT(DE_FALSE);
			return false;
	}
}

static bool isDepthFormat (const tcu::TextureFormat& fmt)
{
	return fmt.order == tcu::TextureFormat::D || fmt.order == tcu::TextureFormat::DS;
}

static bool isColorRenderableFormat (glw::GLenum internalFormat)
{
	return	internalFormat == GL_RGB565			||
			internalFormat == GL_RGBA4			||
			internalFormat == GL_RGB5_A1		||
			internalFormat == GL_RGB10_A2		||
			internalFormat == GL_RGB10_A2UI		||
			internalFormat == GL_SRGB8_ALPHA8	||
			internalFormat == GL_R8				||
			internalFormat == GL_RG8			||
			internalFormat == GL_RGB8			||
			internalFormat == GL_RGBA8			||
			internalFormat == GL_R8I			||
			internalFormat == GL_RG8I			||
			internalFormat == GL_RGBA8I			||
			internalFormat == GL_R8UI			||
			internalFormat == GL_RG8UI			||
			internalFormat == GL_RGBA8UI		||
			internalFormat == GL_R16I			||
			internalFormat == GL_RG16I			||
			internalFormat == GL_RGBA16I		||
			internalFormat == GL_R16UI			||
			internalFormat == GL_RG16UI			||
			internalFormat == GL_RGBA16UI		||
			internalFormat == GL_R32I			||
			internalFormat == GL_RG32I			||
			internalFormat == GL_RGBA32I		||
			internalFormat == GL_R32UI			||
			internalFormat == GL_RG32UI			||
			internalFormat == GL_RGBA32UI;
}

static bool isRenderableFormat (glw::GLenum internalFormat)
{
	return	isColorRenderableFormat(internalFormat)	||
			internalFormat == GL_DEPTH_COMPONENT16	||
			internalFormat == GL_DEPTH_COMPONENT24	||
			internalFormat == GL_DEPTH_COMPONENT32F	||
			internalFormat == GL_DEPTH24_STENCIL8	||
			internalFormat == GL_DEPTH32F_STENCIL8;
}

static bool isTextureBufferFormat (glw::GLenum internalFormat)
{
	return	internalFormat == GL_R8			||
			internalFormat == GL_R16F		||
			internalFormat == GL_R32F		||
			internalFormat == GL_R8I		||
			internalFormat == GL_R16I		||
			internalFormat == GL_R32I		||
			internalFormat == GL_R8UI		||
			internalFormat == GL_R16UI		||
			internalFormat == GL_R32UI		||
			internalFormat == GL_RG8		||
			internalFormat == GL_RG16F		||
			internalFormat == GL_RG32F		||
			internalFormat == GL_RG8I		||
			internalFormat == GL_RG16I		||
			internalFormat == GL_RG32I		||
			internalFormat == GL_RG8UI		||
			internalFormat == GL_RG16UI		||
			internalFormat == GL_RG32UI		||
			internalFormat == GL_RGB32F		||
			internalFormat == GL_RGB32I		||
			internalFormat == GL_RGB32UI	||
			internalFormat == GL_RGBA8		||
			internalFormat == GL_RGBA16F	||
			internalFormat == GL_RGBA32F	||
			internalFormat == GL_RGBA8I		||
			internalFormat == GL_RGBA16I	||
			internalFormat == GL_RGBA32I	||
			internalFormat == GL_RGBA8UI	||
			internalFormat == GL_RGBA16UI	||
			internalFormat == GL_RGBA32UI;
}

static bool isLegalFormatForTarget (glw::GLenum target, glw::GLenum format)
{
	const tcu::TextureFormat fmt = glu::mapGLInternalFormat(format);

	if (target == GL_TEXTURE_3D && isDepthFormat(fmt))
		return false;
	if ((target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) && !isRenderableFormat(format))
		return false;
	if (target == GL_TEXTURE_BUFFER || !isTextureBufferFormat(format))
		return false;
	return true;
}

static bool isCompressionSupportedForTarget (glw::GLenum target)
{
	return target == GL_TEXTURE_2D || target == GL_TEXTURE_2D_ARRAY;
}

static bool isMultisampleTarget (glw::GLenum target)
{
	return target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
}

static bool targetSupportsMipLevels (glw::GLenum target)
{
	return	target != GL_TEXTURE_2D_MULTISAMPLE &&
			target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY &&
			target != GL_TEXTURE_BUFFER;
}

static int getPixelSize (glw::GLenum internalFormat)
{
	const tcu::TextureFormat fmt = glu::mapGLInternalFormat(internalFormat);
	return fmt.getPixelSize();
}

static void generateColorTextureGenerationGroup (std::vector<TextureGenerationSpec>& group, glw::GLenum target, int maxSamples, glw::GLenum internalFormat)
{
	const glw::GLenum queryTarget = (target == GL_TEXTURE_CUBE_MAP) ? (GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) : (target);

	// initial
	{
		TextureGenerationSpec texGen;
		texGen.bindTarget		= target;
		texGen.queryTarget		= queryTarget;
		texGen.immutable		= true;
		texGen.sampleCount		= 0;
		texGen.description		= glu::getTextureTargetStr(target).toString() + ", initial values";

		group.push_back(texGen);
	}

	// ms targets
	if (isMultisampleTarget(target))
	{
		{
			TextureGenerationSpec					texGen;
			TextureGenerationSpec::TextureLevelSpec	level;

			texGen.bindTarget		= target;
			texGen.queryTarget		= queryTarget;
			texGen.immutable		= true;
			texGen.sampleCount		= 1;
			texGen.fixedSamplePos	= false;
			texGen.description		= glu::getTextureTargetStr(target).toString() + ", low sample count";

			level.width				= 16;
			level.height			= 16;
			level.depth				= (textureTypeHasDepth(texGen.bindTarget)) ? (6) : (1);
			level.level				= 0;
			level.internalFormat	= internalFormat;
			level.compressed		= false;

			texGen.levels.push_back(level);
			group.push_back(texGen);
		}
		{
			TextureGenerationSpec					texGen;
			TextureGenerationSpec::TextureLevelSpec	level;

			texGen.bindTarget		= target;
			texGen.queryTarget		= queryTarget;
			texGen.immutable		= true;
			texGen.sampleCount		= maxSamples;
			texGen.fixedSamplePos	= false;
			texGen.description		= glu::getTextureTargetStr(target).toString() + ", high sample count";

			level.width				= 32;
			level.height			= 32;
			level.depth				= (textureTypeHasDepth(texGen.bindTarget)) ? (6) : (1);
			level.level				= 0;
			level.internalFormat	= internalFormat;
			level.compressed		= false;

			texGen.levels.push_back(level);
			group.push_back(texGen);
		}
		{
			TextureGenerationSpec					texGen;
			TextureGenerationSpec::TextureLevelSpec	level;

			texGen.bindTarget		= target;
			texGen.queryTarget		= queryTarget;
			texGen.immutable		= true;
			texGen.sampleCount		= maxSamples;
			texGen.fixedSamplePos	= true;
			texGen.description		= glu::getTextureTargetStr(target).toString() + ", fixed sample positions";

			level.width				= 32;
			level.height			= 32;
			level.depth				= (textureTypeHasDepth(texGen.bindTarget)) ? (6) : (1);
			level.level				= 0;
			level.internalFormat	= internalFormat;
			level.compressed		= false;

			texGen.levels.push_back(level);
			group.push_back(texGen);
		}
	}
	else if (target == GL_TEXTURE_BUFFER)
	{
		// whole buffer
		{
			TextureGenerationSpec					texGen;
			TextureGenerationSpec::TextureLevelSpec	level;
			const int								baseSize = getPixelSize(internalFormat);

			texGen.bindTarget			= target;
			texGen.queryTarget			= queryTarget;
			texGen.immutable			= true;
			texGen.description			= glu::getTextureTargetStr(target).toString() + ", whole buffer";
			texGen.texBufferDataOffset	= 0;
			texGen.texBufferDataSize	= 32 * baseSize + (baseSize - 1);
			texGen.bindWholeArray		= true;

			level.width				= 32;
			level.height			= 1;
			level.depth				= 1;
			level.level				= 0;
			level.internalFormat	= internalFormat;
			level.compressed		= false;

			texGen.levels.push_back(level);
			group.push_back(texGen);
		}
		// partial buffer
		{
			TextureGenerationSpec					texGen;
			TextureGenerationSpec::TextureLevelSpec	level;
			const int								baseSize = getPixelSize(internalFormat);

			texGen.bindTarget			= target;
			texGen.queryTarget			= queryTarget;
			texGen.immutable			= true;
			texGen.description			= glu::getTextureTargetStr(target).toString() + ", partial buffer";
			texGen.texBufferDataOffset	= 256;
			texGen.texBufferDataSize	= 16 * baseSize + (baseSize - 1);
			texGen.bindWholeArray		= false;

			level.width				= 16;
			level.height			= 1;
			level.depth				= 1;
			level.level				= 0;
			level.internalFormat	= internalFormat;
			level.compressed		= false;

			texGen.levels.push_back(level);
			group.push_back(texGen);
		}
	}
	else
	{
		// immutable
		{
			TextureGenerationSpec					texGen;
			TextureGenerationSpec::TextureLevelSpec	level;

			texGen.bindTarget		= target;
			texGen.queryTarget		= queryTarget;
			texGen.immutable		= true;
			texGen.description		= glu::getTextureTargetStr(target).toString() + ", immutable";

			level.width				= 32;
			level.height			= 32;
			level.depth				= (textureTypeHasDepth(texGen.bindTarget)) ? (6) : (1);
			level.level				= 0;
			level.internalFormat	= internalFormat;
			level.compressed		= false;

			texGen.levels.push_back(level);
			group.push_back(texGen);
		}
		// mutable
		{
			TextureGenerationSpec					texGen;
			TextureGenerationSpec::TextureLevelSpec	level;

			texGen.bindTarget		= target;
			texGen.queryTarget		= queryTarget;
			texGen.immutable		= false;
			texGen.description		= glu::getTextureTargetStr(target).toString() + ", mutable";

			level.width				= 16;
			level.height			= (target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) ? (16) : (64);
			level.depth				= (textureTypeHasDepth(texGen.bindTarget)) ? (6) : (1);
			level.level				= 0;
			level.internalFormat	= internalFormat;
			level.compressed		= false;

			texGen.levels.push_back(level);
			group.push_back(texGen);
		}
		// mip3
		{
			TextureGenerationSpec					texGen;
			TextureGenerationSpec::TextureLevelSpec	level;

			texGen.bindTarget		= target;
			texGen.queryTarget		= queryTarget;
			texGen.immutable		= false;
			texGen.description		= glu::getTextureTargetStr(target).toString() + ", mip level 3";

			level.width				= 4;
			level.height			= (target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) ? (4) : (8);
			level.depth				= (textureTypeHasDepth(texGen.bindTarget)) ? (6) : (1);
			level.level				= 3;
			level.internalFormat	= internalFormat;
			level.compressed		= false;

			texGen.levels.push_back(level);
			group.push_back(texGen);
		}
	}
}

static void generateInternalFormatTextureGenerationGroup (std::vector<TextureGenerationSpec>& group, glw::GLenum target)
{
	const glw::GLenum queryTarget = (target == GL_TEXTURE_CUBE_MAP) ? (GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) : (target);

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

		GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16,
		GL_DEPTH32F_STENCIL8, GL_DEPTH24_STENCIL8
	};

	// initial
	{
		TextureGenerationSpec texGen;
		texGen.bindTarget		= target;
		texGen.queryTarget		= queryTarget;
		texGen.immutable		= true;
		texGen.sampleCount		= 0;
		texGen.fixedSamplePos	= true;
		texGen.description		= glu::getTextureTargetStr(target).toString() + ", initial values";

		group.push_back(texGen);
	}

	// test all formats
	for (int internalFormatNdx = 0; internalFormatNdx < DE_LENGTH_OF_ARRAY(internalFormats); ++internalFormatNdx)
	{
		if (!isLegalFormatForTarget(target, internalFormats[internalFormatNdx]))
			continue;

		const int								baseSize = getPixelSize(internalFormats[internalFormatNdx]);
		TextureGenerationSpec					texGen;
		TextureGenerationSpec::TextureLevelSpec	level;

		texGen.bindTarget		= target;
		texGen.queryTarget		= queryTarget;
		texGen.immutable		= true;
		texGen.sampleCount		= (isMultisampleTarget(target) ? (1) : (0));
		texGen.description		= glu::getTextureTargetStr(target).toString() + ", internal format " + glu::getTextureFormatName(internalFormats[internalFormatNdx]);

		if (target == GL_TEXTURE_BUFFER)
		{
			texGen.texBufferDataOffset	= 0;
			texGen.texBufferDataSize	= 32 * baseSize + (baseSize - 1);
			texGen.bindWholeArray		= true;
		}

		level.width				= 32;
		level.height			= (textureTypeHasHeight(target)) ? (32) : (1);
		level.depth				= (textureTypeHasDepth(target)) ? (6) : (1);
		level.level				= 0;
		level.internalFormat	= internalFormats[internalFormatNdx];
		level.compressed		= false;

		texGen.levels.push_back(level);
		group.push_back(texGen);
	}

	// test mutable rgba8 with mip level 3
	if (targetSupportsMipLevels(target))
	{
		TextureGenerationSpec					texGen;
		TextureGenerationSpec::TextureLevelSpec	level;

		texGen.bindTarget		= target;
		texGen.queryTarget		= queryTarget;
		texGen.immutable		= false;
		texGen.description		= glu::getTextureTargetStr(target).toString() + ", internal format GL_RGBA8, mip level 3";

		level.width				= 32;
		level.height			= 32;
		level.depth				= (textureTypeHasDepth(target)) ? (6) : (1);
		level.level				= 3;
		level.internalFormat	= GL_RGBA8;
		level.compressed		= false;

		texGen.levels.push_back(level);
		group.push_back(texGen);
	}
}

static void generateCompressedTextureGenerationGroup (std::vector<TextureGenerationSpec>& group, glw::GLenum target)
{
	const glw::GLenum queryTarget = (target == GL_TEXTURE_CUBE_MAP) ? (GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) : (target);

	// initial
	{
		TextureGenerationSpec texGen;
		texGen.bindTarget	= target;
		texGen.queryTarget	= queryTarget;
		texGen.immutable	= true;
		texGen.description	= glu::getTextureTargetStr(target).toString() + ", initial values";

		group.push_back(texGen);
	}

	// compressed
	if (isCompressionSupportedForTarget(target))
	{
		TextureGenerationSpec					texGen;
		TextureGenerationSpec::TextureLevelSpec	level;

		texGen.bindTarget		= target;
		texGen.queryTarget		= queryTarget;
		texGen.immutable		= false;
		texGen.description		= glu::getTextureTargetStr(target).toString() + ", compressed";

		level.width				= 32;
		level.height			= 32;
		level.depth				= (target == GL_TEXTURE_2D_ARRAY) ? (2) : (1);
		level.level				= 0;
		level.internalFormat	= GL_COMPRESSED_RGB8_ETC2;
		level.compressed		= true;

		texGen.levels.push_back(level);
		group.push_back(texGen);
	}
}

static void generateTextureBufferGenerationGroup (std::vector<TextureGenerationSpec>& group, glw::GLenum target)
{
	const glw::GLenum queryTarget = (target == GL_TEXTURE_CUBE_MAP) ? (GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) : (target);

	// initial
	{
		TextureGenerationSpec texGen;
		texGen.bindTarget		= target;
		texGen.queryTarget		= queryTarget;
		texGen.immutable		= true;
		texGen.sampleCount		= 0;
		texGen.description		= glu::getTextureTargetStr(target).toString() + ", initial values";

		group.push_back(texGen);
	}

	// actual specification tests are in texture_buffer tests, no need to do them here too
}

bool applyTextureGenerationSpec (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec, glw::GLuint& texBuffer)
{
	bool allOk = true;

	DE_ASSERT(!(spec.immutable && spec.levels.size() > 1));		// !< immutable textures have only one level

	for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx)
	{
		const glu::TransferFormat transferFormat = (spec.levels[levelNdx].compressed) ? (glu::TransferFormat()) : (glu::getTransferFormat(glu::mapGLInternalFormat(spec.levels[levelNdx].internalFormat)));

		if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D)
			gl.glTexStorage2D(spec.bindTarget, 1, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height);
		else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_3D)
			gl.glTexStorage3D(spec.bindTarget, 1, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, spec.levels[levelNdx].depth);
		else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D_ARRAY)
			gl.glTexStorage3D(spec.bindTarget, 1, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, spec.levels[levelNdx].depth);
		else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_CUBE_MAP)
			gl.glTexStorage2D(spec.bindTarget, 1, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height);
		else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D_MULTISAMPLE)
			gl.glTexStorage2DMultisample(spec.bindTarget, spec.sampleCount, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, (spec.fixedSamplePos) ? (GL_TRUE) : (GL_FALSE));
		else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
			gl.glTexStorage3DMultisample(spec.bindTarget, spec.sampleCount, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, spec.levels[levelNdx].depth, (spec.fixedSamplePos) ? (GL_TRUE) : (GL_FALSE));
		else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_CUBE_MAP_ARRAY)
			gl.glTexStorage3D(spec.bindTarget, 1, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, spec.levels[levelNdx].depth);
		else if (!spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D)
			gl.glTexImage2D(spec.bindTarget, spec.levels[levelNdx].level, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, 0, transferFormat.format, transferFormat.dataType, DE_NULL);
		else if (!spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_3D)
			gl.glTexImage3D(spec.bindTarget, spec.levels[levelNdx].level, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, spec.levels[levelNdx].depth, 0, transferFormat.format, transferFormat.dataType, DE_NULL);
		else if (!spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D_ARRAY)
			gl.glTexImage3D(spec.bindTarget, spec.levels[levelNdx].level, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, spec.levels[levelNdx].depth, 0, transferFormat.format, transferFormat.dataType, DE_NULL);
		else if (!spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_CUBE_MAP)
			gl.glTexImage2D(spec.queryTarget, spec.levels[levelNdx].level, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, 0, transferFormat.format, transferFormat.dataType, DE_NULL);
		else if (!spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_CUBE_MAP_ARRAY)
			gl.glTexImage3D(spec.bindTarget, spec.levels[levelNdx].level, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, spec.levels[levelNdx].depth, 0, transferFormat.format, transferFormat.dataType, DE_NULL);
		else if (!spec.immutable && spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D)
		{
			DE_ASSERT(spec.levels[levelNdx].width == 32);
			DE_ASSERT(spec.levels[levelNdx].height == 32);
			DE_ASSERT(spec.levels[levelNdx].internalFormat == GL_COMPRESSED_RGB8_ETC2);

			static const deUint8 buffer[64 * 8] = { 0 };
			gl.glCompressedTexImage2D(spec.bindTarget, spec.levels[levelNdx].level, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, 0, sizeof(buffer), buffer);
		}
		else if (!spec.immutable && spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D_ARRAY)
		{
			DE_ASSERT(spec.levels[levelNdx].width == 32);
			DE_ASSERT(spec.levels[levelNdx].height == 32);
			DE_ASSERT(spec.levels[levelNdx].depth == 2);
			DE_ASSERT(spec.levels[levelNdx].internalFormat == GL_COMPRESSED_RGB8_ETC2);

			static const deUint8 buffer[64 * 8 * 2] = { 0 };
			gl.glCompressedTexImage3D(spec.bindTarget, spec.levels[levelNdx].level, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, spec.levels[levelNdx].depth, 0, sizeof(buffer), buffer);
		}
		else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_BUFFER)
		{
			gl.glGenBuffers(1, &texBuffer);
			gl.glBindBuffer(GL_TEXTURE_BUFFER, texBuffer);

			if (spec.bindWholeArray)
			{
				gl.glBufferData(GL_TEXTURE_BUFFER, spec.texBufferDataSize, DE_NULL, GL_STATIC_DRAW);
				gl.glTexBuffer(GL_TEXTURE_BUFFER, spec.levels[levelNdx].internalFormat, texBuffer);
			}
			else
			{
				gl.glBufferData(GL_TEXTURE_BUFFER, spec.texBufferDataOffset + spec.texBufferDataSize, DE_NULL, GL_STATIC_DRAW);
				gl.glTexBufferRange(GL_TEXTURE_BUFFER, spec.levels[levelNdx].internalFormat, texBuffer, spec.texBufferDataOffset, spec.texBufferDataSize);
			}
		}
		else
			DE_ASSERT(DE_FALSE);

		{
			const glw::GLenum err = gl.glGetError();
			if (err != GL_NO_ERROR)
			{
				gl.getLog()	<< tcu::TestLog::Message
							<< "Texture specification failed, got " + glu::getErrorStr(err).toString()
							<< tcu::TestLog::EndMessage;
				allOk = false;
			}
		}
	}

	return allOk;
}

class TextureLevelCase : public TestCase
{
public:
										TextureLevelCase		(Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type);
										~TextureLevelCase		(void);

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

protected:
	void								getFormatSamples		(glw::GLenum internalFormat, std::vector<int>& samples);
	bool								testConfig				(const TextureGenerationSpec& spec);
	virtual bool						checkTextureState		(glu::CallLogWrapper& gl, const TextureGenerationSpec& spec) = 0;
	virtual void						generateTestIterations	(std::vector<TextureGenerationSpec>& iterations) = 0;

	const QueryType						m_type;
	const glw::GLenum					m_target;
	glw::GLuint							m_texture;
	glw::GLuint							m_texBuffer;

private:
	int									m_iteration;
	std::vector<TextureGenerationSpec>	m_iterations;
	bool								m_allIterationsOk;
	std::vector<int>					m_failedIterations;
};

TextureLevelCase::TextureLevelCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
	: TestCase			(ctx, name, desc)
	, m_type			(type)
	, m_target			(target)
	, m_texture			(0)
	, m_texBuffer		(0)
	, m_iteration		(0)
	, m_allIterationsOk	(true)
{
}

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

void TextureLevelCase::init (void)
{
	if (!isCoreTextureTarget(m_target, m_context.getRenderContext().getType()))
	{
		const char* const targetExtension = getTextureTargetExtension(m_target);

		if (!m_context.getContextInfo().isExtensionSupported(targetExtension))
			throw tcu::NotSupportedError("Test requires " + std::string(targetExtension) + " extension");
	}

	generateTestIterations(m_iterations);

	for (int iterationNdx = 0; iterationNdx < (int)m_iterations.size(); ++iterationNdx)
		DE_ASSERT(m_iterations[iterationNdx].bindTarget == m_target);
}

void TextureLevelCase::deinit (void)
{
	if (m_texture)
	{
		m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texture);
		m_texture = 0;
	}
	if (m_texBuffer)
	{
		m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texBuffer);
		m_texBuffer = 0;
	}
}

void TextureLevelCase::getFormatSamples (glw::GLenum internalFormat, std::vector<int>& samples)
{
	const glw::Functions	gl			= m_context.getRenderContext().getFunctions();
	int						sampleCount	= -1;

	if (!isMultisampleTarget(m_target))
		return;

	gl.getInternalformativ(m_target, internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &sampleCount);

	if (sampleCount < 0)
		throw tcu::TestError("internal format query failed");

	samples.resize(sampleCount);

	if (sampleCount > 0)
	{
		gl.getInternalformativ(m_target, internalFormat, GL_SAMPLES, sampleCount, &samples[0]);
		GLU_EXPECT_NO_ERROR(gl.getError(), "get max samples");
	}
}

TextureLevelCase::IterateResult TextureLevelCase::iterate (void)
{
	const bool result = testConfig(m_iterations[m_iteration]);

	if (!result)
	{
		m_failedIterations.push_back(m_iteration);
		m_allIterationsOk = false;
	}

	if (++m_iteration < (int)m_iterations.size())
		return CONTINUE;

	if (m_allIterationsOk)
		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
	else
	{
		tcu::MessageBuilder msg(&m_testCtx.getLog());

		msg << "Following iteration(s) failed: ";
		for (int ndx = 0; ndx < (int)m_failedIterations.size(); ++ndx)
		{
			if (ndx)
				msg << ", ";
			msg << (m_failedIterations[ndx] + 1);
		}
		msg << tcu::TestLog::EndMessage;

		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more iterations failed");
	}
	return STOP;
}

bool TextureLevelCase::testConfig (const TextureGenerationSpec& spec)
{
	const tcu::ScopedLogSection section(m_testCtx.getLog(), "Iteration", std::string() + "Iteration " + de::toString(m_iteration+1) + "/" + de::toString((int)m_iterations.size()) + " - " + spec.description);
	glu::CallLogWrapper			gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
	bool						result;

	gl.enableLogging(true);

	gl.glGenTextures(1, &m_texture);
	gl.glBindTexture(spec.bindTarget, m_texture);
	GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen tex");

	// Set the state
	applyTextureGenerationSpec(gl, spec, m_texBuffer);

	// Verify the state
	result = checkTextureState(gl, spec);

	gl.glDeleteTextures(1, &m_texture);
	m_texture = 0;

	if (m_texBuffer)
	{
		gl.glDeleteBuffers(1, &m_texBuffer);
		m_texture = 0;
	}

	return result;
}

/*--------------------------------------------------------------------*//*!
 * \brief Test texture target
 *//*--------------------------------------------------------------------*/
class TextureLevelCommonCase : public TextureLevelCase
{
public:
						TextureLevelCommonCase	(Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type);

protected:
	virtual void		generateTestIterations	(std::vector<TextureGenerationSpec>& iterations);
};

TextureLevelCommonCase::TextureLevelCommonCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
	: TextureLevelCase(ctx, name, desc, target, type)
{
}

void TextureLevelCommonCase::generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
{
	const glw::GLenum	internalFormat = GL_RGBA8;
	int					maxSamples;
	std::vector<int>	samples;

	getFormatSamples(internalFormat, samples);
	if (samples.empty())
		maxSamples = -1;
	else
		maxSamples = samples[0];

	generateColorTextureGenerationGroup(iterations, m_target, maxSamples, internalFormat);
}

class TextureLevelSampleCase : public TextureLevelCommonCase
{
public:
	TextureLevelSampleCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
		: TextureLevelCommonCase(ctx, name, desc, target, type)
	{
	}

private:
	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
	{
		const int queryLevel	= (spec.levels.empty()) ? (0) : (spec.levels[0].level);
		const int refValue		= (spec.levels.empty()) ? (0) : (spec.sampleCount);

		return verifyTextureLevelParameterGreaterOrEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_SAMPLES, refValue, m_type);
	}
};

class TextureLevelFixedSamplesCase : public TextureLevelCommonCase
{
public:
	TextureLevelFixedSamplesCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
		: TextureLevelCommonCase(ctx, name, desc, target, type)
	{
	}

private:
	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
	{
		const int queryLevel	= (spec.levels.empty()) ? (0) : (spec.levels[0].level);
		const int refValue		= (spec.levels.empty()) ? (1) : ((spec.fixedSamplePos) ? (1) : (0));

		return verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_FIXED_SAMPLE_LOCATIONS, refValue, m_type);
	}
};

class TextureLevelWidthCase : public TextureLevelCommonCase
{
public:
	TextureLevelWidthCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
		: TextureLevelCommonCase(ctx, name, desc, target, type)
	{
	}

private:
	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
	{
		const int	initialValue	= 0;
		bool		allOk			= true;

		if (spec.levels.empty())
		{
			const int queryLevel	= 0;
			const int refValue		= initialValue;

			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_WIDTH, refValue, m_type);
		}
		else
		{
			for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx)
			{
				const int queryLevel	= spec.levels[levelNdx].level;
				const int refValue		= spec.levels[levelNdx].width;

				allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_WIDTH, refValue, m_type);
			}
		}

		return allOk;
	}
};

class TextureLevelHeightCase : public TextureLevelCommonCase
{
public:
	TextureLevelHeightCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
		: TextureLevelCommonCase(ctx, name, desc, target, type)
	{
	}

private:
	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
	{
		const int	initialValue	= 0;
		bool		allOk			= true;

		if (spec.levels.empty())
		{
			const int queryLevel	= 0;
			const int refValue		= initialValue;

			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_HEIGHT, refValue, m_type);
		}
		else
		{
			for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx)
			{
				const int queryLevel	= spec.levels[levelNdx].level;
				const int refValue		= spec.levels[levelNdx].height;

				allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_HEIGHT, refValue, m_type);
			}
		}

		return allOk;
	}
};

class TextureLevelDepthCase : public TextureLevelCommonCase
{
public:
	TextureLevelDepthCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
		: TextureLevelCommonCase(ctx, name, desc, target, type)
	{
	}

private:

	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
	{
		const int	initialValue	= 0;
		bool		allOk			= true;

		if (spec.levels.empty())
		{
			const int queryLevel	= 0;
			const int refValue		= initialValue;

			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_DEPTH, refValue, m_type);
		}
		else
		{
			for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx)
			{
				const int queryLevel	= spec.levels[levelNdx].level;
				const int refValue		= spec.levels[levelNdx].depth;

				allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_DEPTH, refValue, m_type);
			}
		}

		return allOk;
	}
};

class TextureLevelInternalFormatCase : public TextureLevelCase
{
public:
	TextureLevelInternalFormatCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
		: TextureLevelCase(ctx, name, desc, target, type)
	{
	}

private:
	void generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
	{
		generateInternalFormatTextureGenerationGroup(iterations, m_target);
	}

	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
	{
		bool allOk = true;

		if (spec.levels.empty())
		{
			const int queryLevel		= 0;
			const int initialValues[2]	= { GL_RGBA, GL_R8 };

			allOk &= verifyTextureLevelParameterInternalFormatAnyOf(gl, spec.queryTarget, queryLevel, GL_TEXTURE_INTERNAL_FORMAT, initialValues, DE_LENGTH_OF_ARRAY(initialValues), m_type);
		}
		else
		{
			for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx)
			{
				const int queryLevel	= spec.levels[levelNdx].level;
				const int refValue		= spec.levels[levelNdx].internalFormat;

				allOk &= verifyTextureLevelParameterInternalFormatEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_INTERNAL_FORMAT, refValue, m_type);
			}
		}

		return allOk;
	}
};

class TextureLevelSizeCase : public TextureLevelCase
{
public:
						TextureLevelSizeCase			(Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type, glw::GLenum pname);

private:
	void				generateTestIterations			(std::vector<TextureGenerationSpec>& iterations);
	bool				checkTextureState				(glu::CallLogWrapper& gl, const TextureGenerationSpec& spec);
	int					getMinimumComponentResolution	(glw::GLenum internalFormat);

	const glw::GLenum	m_pname;
};

TextureLevelSizeCase::TextureLevelSizeCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type, glw::GLenum pname)
	: TextureLevelCase	(ctx, name, desc, target, type)
	, m_pname			(pname)
{
}

void TextureLevelSizeCase::generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
{
	generateInternalFormatTextureGenerationGroup(iterations, m_target);
}

bool TextureLevelSizeCase::checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
{
	bool allOk = true;

	if (spec.levels.empty())
	{
		allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, m_pname, 0, m_type);
	}
	else
	{
		for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx)
		{
			const int queryLevel	= spec.levels[levelNdx].level;
			const int refValue		= getMinimumComponentResolution(spec.levels[levelNdx].internalFormat);

			allOk &= verifyTextureLevelParameterGreaterOrEqual(gl, spec.queryTarget, queryLevel, m_pname, refValue, m_type);
		}
	}

	return allOk;
}

int TextureLevelSizeCase::getMinimumComponentResolution (glw::GLenum internalFormat)
{
	const tcu::TextureFormat	format			= glu::mapGLInternalFormat(internalFormat);
	const tcu::IVec4			channelBitDepth	= tcu::getTextureFormatBitDepth(format);

	switch (m_pname)
	{
		case GL_TEXTURE_RED_SIZE:
			if (format.order == tcu::TextureFormat::R		||
				format.order == tcu::TextureFormat::RG		||
				format.order == tcu::TextureFormat::RGB		||
				format.order == tcu::TextureFormat::RGBA	||
				format.order == tcu::TextureFormat::BGRA	||
				format.order == tcu::TextureFormat::ARGB	||
				format.order == tcu::TextureFormat::sRGB	||
				format.order == tcu::TextureFormat::sRGBA)
				return channelBitDepth[0];
			else
				return 0;

		case GL_TEXTURE_GREEN_SIZE:
			if (format.order == tcu::TextureFormat::RG		||
				format.order == tcu::TextureFormat::RGB		||
				format.order == tcu::TextureFormat::RGBA	||
				format.order == tcu::TextureFormat::BGRA	||
				format.order == tcu::TextureFormat::ARGB	||
				format.order == tcu::TextureFormat::sRGB	||
				format.order == tcu::TextureFormat::sRGBA)
				return channelBitDepth[1];
			else
				return 0;

		case GL_TEXTURE_BLUE_SIZE:
			if (format.order == tcu::TextureFormat::RGB		||
				format.order == tcu::TextureFormat::RGBA	||
				format.order == tcu::TextureFormat::BGRA	||
				format.order == tcu::TextureFormat::ARGB	||
				format.order == tcu::TextureFormat::sRGB	||
				format.order == tcu::TextureFormat::sRGBA)
				return channelBitDepth[2];
			else
				return 0;

		case GL_TEXTURE_ALPHA_SIZE:
			if (format.order == tcu::TextureFormat::RGBA	||
				format.order == tcu::TextureFormat::BGRA	||
				format.order == tcu::TextureFormat::ARGB	||
				format.order == tcu::TextureFormat::sRGBA)
				return channelBitDepth[3];
			else
				return 0;

		case GL_TEXTURE_DEPTH_SIZE:
			if (format.order == tcu::TextureFormat::D	||
				format.order == tcu::TextureFormat::DS)
				return channelBitDepth[0];
			else
				return 0;

		case GL_TEXTURE_STENCIL_SIZE:
			if (format.order == tcu::TextureFormat::DS)
				return channelBitDepth[3];
			else
				return 0;

		case GL_TEXTURE_SHARED_SIZE:
			if (internalFormat == GL_RGB9_E5)
				return 5;
			else
				return 0;
		default:
			DE_ASSERT(DE_FALSE);
			return 0;
	}
}

class TextureLevelTypeCase : public TextureLevelCase
{
public:
						TextureLevelTypeCase			(Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type, glw::GLenum pname);

private:
	void				generateTestIterations			(std::vector<TextureGenerationSpec>& iterations);
	bool				checkTextureState				(glu::CallLogWrapper& gl, const TextureGenerationSpec& spec);
	int					getComponentType				(glw::GLenum internalFormat);

	const glw::GLenum	m_pname;
};

TextureLevelTypeCase::TextureLevelTypeCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type, glw::GLenum pname)
	: TextureLevelCase	(ctx, name, desc, target, type)
	, m_pname			(pname)
{
}

void TextureLevelTypeCase::generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
{
	generateInternalFormatTextureGenerationGroup(iterations, m_target);
}

bool TextureLevelTypeCase::checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
{
	bool allOk = true;

	if (spec.levels.empty())
	{
		allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, m_pname, GL_NONE, m_type);
	}
	else
	{
		for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx)
		{
			const int queryLevel	= spec.levels[levelNdx].level;
			const int refValue		= getComponentType(spec.levels[levelNdx].internalFormat);

			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, m_pname, refValue, m_type);
		}
	}

	return allOk;
}

int TextureLevelTypeCase::getComponentType (glw::GLenum internalFormat)
{
	const tcu::TextureFormat		format			= glu::mapGLInternalFormat(internalFormat);
	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
	glw::GLenum						channelType		= GL_NONE;

	// depth-stencil special cases
	if (format.type == tcu::TextureFormat::UNSIGNED_INT_24_8)
	{
		if (m_pname == GL_TEXTURE_DEPTH_TYPE)
			return GL_UNSIGNED_NORMALIZED;
		else
			return GL_NONE;
	}
	else if (format.type == tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV)
	{
		if (m_pname == GL_TEXTURE_DEPTH_TYPE)
			return GL_FLOAT;
		else
			return GL_NONE;
	}
	else
	{
		switch (channelClass)
		{
			case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:		channelType = GL_SIGNED_NORMALIZED;		break;
			case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:		channelType = GL_UNSIGNED_NORMALIZED;	break;
			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:			channelType = GL_INT;					break;
			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:			channelType = GL_UNSIGNED_INT;			break;
			case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:			channelType = GL_FLOAT;					break;
			default:
				DE_ASSERT(DE_FALSE);
		}
	}

	switch (m_pname)
	{
		case GL_TEXTURE_RED_TYPE:
			if (format.order == tcu::TextureFormat::R		||
				format.order == tcu::TextureFormat::RG		||
				format.order == tcu::TextureFormat::RGB		||
				format.order == tcu::TextureFormat::RGBA	||
				format.order == tcu::TextureFormat::BGRA	||
				format.order == tcu::TextureFormat::ARGB	||
				format.order == tcu::TextureFormat::sRGB	||
				format.order == tcu::TextureFormat::sRGBA)
				return channelType;
			else
				return GL_NONE;

		case GL_TEXTURE_GREEN_TYPE:
			if (format.order == tcu::TextureFormat::RG		||
				format.order == tcu::TextureFormat::RGB		||
				format.order == tcu::TextureFormat::RGBA	||
				format.order == tcu::TextureFormat::BGRA	||
				format.order == tcu::TextureFormat::ARGB	||
				format.order == tcu::TextureFormat::sRGB	||
				format.order == tcu::TextureFormat::sRGBA)
				return channelType;
			else
				return GL_NONE;

		case GL_TEXTURE_BLUE_TYPE:
			if (format.order == tcu::TextureFormat::RGB		||
				format.order == tcu::TextureFormat::RGBA	||
				format.order == tcu::TextureFormat::BGRA	||
				format.order == tcu::TextureFormat::ARGB	||
				format.order == tcu::TextureFormat::sRGB	||
				format.order == tcu::TextureFormat::sRGBA)
				return channelType;
			else
				return GL_NONE;

		case GL_TEXTURE_ALPHA_TYPE:
			if (format.order == tcu::TextureFormat::RGBA	||
				format.order == tcu::TextureFormat::BGRA	||
				format.order == tcu::TextureFormat::ARGB	||
				format.order == tcu::TextureFormat::sRGBA)
				return channelType;
			else
				return GL_NONE;

		case GL_TEXTURE_DEPTH_TYPE:
			if (format.order == tcu::TextureFormat::D	||
				format.order == tcu::TextureFormat::DS)
				return channelType;
			else
				return GL_NONE;

		default:
			DE_ASSERT(DE_FALSE);
			return 0;
	}
}

class TextureLevelCompressedCase : public TextureLevelCase
{
public:
	TextureLevelCompressedCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
		: TextureLevelCase(ctx, name, desc, target, type)
	{
	}

private:
	void generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
	{
		generateCompressedTextureGenerationGroup(iterations, m_target);
	}

	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
	{
		bool allOk = true;

		if (spec.levels.empty())
		{
			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, GL_TEXTURE_COMPRESSED, 0, m_type);
		}
		else
		{
			for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx)
			{
				const int queryLevel	= spec.levels[levelNdx].level;
				const int refValue		= (spec.levels[levelNdx].compressed) ? (1) : (0);

				allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_COMPRESSED, refValue, m_type);
			}
		}

		return allOk;
	}
};

static bool checkSupport(Context& ctx)
{
	auto ctxType = ctx.getRenderContext().getType();
	return contextSupports(ctxType, glu::ApiType::es(3, 2)) ||
		   contextSupports(ctxType, glu::ApiType::core(4, 5)) ||
		   ctx.getContextInfo().isExtensionSupported("GL_EXT_texture_buffer");
}

class TextureLevelBufferDataStoreCase : public TextureLevelCase
{
public:
	TextureLevelBufferDataStoreCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
		: TextureLevelCase(ctx, name, desc, target, type)
	{
	}

private:
	void init (void)
	{
		if (!checkSupport(m_context))
			throw tcu::NotSupportedError("Test requires GL_EXT_texture_buffer extension");
		TextureLevelCase::init();
	}

	void generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
	{
		generateTextureBufferGenerationGroup(iterations, m_target);
	}

	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
	{
		bool allOk = true;

		if (spec.levels.empty())
		{
			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, GL_TEXTURE_BUFFER_DATA_STORE_BINDING, 0, m_type);
		}
		else
		{
			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, GL_TEXTURE_BUFFER_DATA_STORE_BINDING, m_texBuffer, m_type);
		}

		return allOk;
	}
};

class TextureLevelBufferDataOffsetCase : public TextureLevelCase
{
public:
	TextureLevelBufferDataOffsetCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
		: TextureLevelCase(ctx, name, desc, target, type)
	{
	}

private:
	void init (void)
	{
		if (!checkSupport(m_context))
			throw tcu::NotSupportedError("Test requires GL_EXT_texture_buffer extension");
		TextureLevelCase::init();
	}

	void generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
	{
		generateTextureBufferGenerationGroup(iterations, m_target);
	}

	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
	{
		bool allOk = true;

		if (spec.levels.empty())
		{
			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, GL_TEXTURE_BUFFER_OFFSET, 0, m_type);
		}
		else
		{
			const int refValue = spec.texBufferDataOffset;

			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, GL_TEXTURE_BUFFER_OFFSET, refValue, m_type);
		}

		return allOk;
	}
};

class TextureLevelBufferDataSizeCase : public TextureLevelCase
{
public:
	TextureLevelBufferDataSizeCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
		: TextureLevelCase(ctx, name, desc, target, type)
	{
	}

private:
	void init (void)
	{
		if (!checkSupport(m_context))
			throw tcu::NotSupportedError("Test requires GL_EXT_texture_buffer extension");
		TextureLevelCase::init();
	}

	void generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
	{
		generateTextureBufferGenerationGroup(iterations, m_target);
	}

	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
	{
		bool allOk = true;

		if (spec.levels.empty())
		{
			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, GL_TEXTURE_BUFFER_SIZE, 0, m_type);
		}
		else
		{
			const int refValue = spec.texBufferDataSize;

			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, GL_TEXTURE_BUFFER_SIZE, refValue, m_type);
		}

		return allOk;
	}
};

} // anonymous

static const char* getVerifierSuffix (QueryType type)
{
	switch (type)
	{
		case QUERY_TEXTURE_LEVEL_FLOAT:		return "_float";
		case QUERY_TEXTURE_LEVEL_INTEGER:	return "_integer";
		default:
			DE_ASSERT(DE_FALSE);
			return DE_NULL;
	}
}

TextureLevelStateQueryTests::TextureLevelStateQueryTests (Context& context)
	: TestCaseGroup(context, "texture_level", "GetTexLevelParameter tests")
{
}

TextureLevelStateQueryTests::~TextureLevelStateQueryTests (void)
{
}

void TextureLevelStateQueryTests::init (void)
{
	static const QueryType verifiers[] =
	{
		QUERY_TEXTURE_LEVEL_INTEGER,
		QUERY_TEXTURE_LEVEL_FLOAT,
	};

#define FOR_EACH_VERIFIER(X) \
	for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx)	\
	{																						\
		const std::string verifierSuffix = getVerifierSuffix(verifiers[verifierNdx]);		\
		const QueryType verifier = verifiers[verifierNdx];									\
		targetGroup->addChild(X);															\
	}
	static const struct
	{
		const char*	name;
		glw::GLenum	target;
	} textureTargets[] =
	{
		{ "texture_2d",						GL_TEXTURE_2D,						},
		{ "texture_3d",						GL_TEXTURE_3D,						},
		{ "texture_2d_array",				GL_TEXTURE_2D_ARRAY,				},
		{ "texture_cube_map",				GL_TEXTURE_CUBE_MAP,				},
		{ "texture_2d_multisample",			GL_TEXTURE_2D_MULTISAMPLE,			},
		{ "texture_2d_multisample_array",	GL_TEXTURE_2D_MULTISAMPLE_ARRAY,	}, // GL_OES_texture_storage_multisample_2d_array
		{ "texture_buffer",					GL_TEXTURE_BUFFER,					}, // GL_EXT_texture_buffer
		{ "texture_cube_array",				GL_TEXTURE_CUBE_MAP_ARRAY,			}, // GL_EXT_texture_cube_map_array
	};

	for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(textureTargets); ++targetNdx)
	{
		tcu::TestCaseGroup* const targetGroup = new tcu::TestCaseGroup(m_testCtx, textureTargets[targetNdx].name, textureTargets[targetNdx].name);
		addChild(targetGroup);

		FOR_EACH_VERIFIER(new TextureLevelSampleCase			(m_context, ("samples" + verifierSuffix).c_str(),					"Verify TEXTURE_SAMPLES",					textureTargets[targetNdx].target,	verifier));
		FOR_EACH_VERIFIER(new TextureLevelFixedSamplesCase		(m_context, ("fixed_sample_locations" + verifierSuffix).c_str(),	"Verify TEXTURE_FIXED_SAMPLE_LOCATIONS",	textureTargets[targetNdx].target,	verifier));
		FOR_EACH_VERIFIER(new TextureLevelWidthCase				(m_context, ("width" + verifierSuffix).c_str(),						"Verify TEXTURE_WIDTH",						textureTargets[targetNdx].target,	verifier));
		FOR_EACH_VERIFIER(new TextureLevelHeightCase			(m_context, ("height" + verifierSuffix).c_str(),					"Verify TEXTURE_HEIGHT",					textureTargets[targetNdx].target,	verifier));
		FOR_EACH_VERIFIER(new TextureLevelDepthCase				(m_context, ("depth" + verifierSuffix).c_str(),						"Verify TEXTURE_DEPTH",						textureTargets[targetNdx].target,	verifier));
		FOR_EACH_VERIFIER(new TextureLevelInternalFormatCase	(m_context, ("internal_format" + verifierSuffix).c_str(),			"Verify TEXTURE_INTERNAL_FORMAT",			textureTargets[targetNdx].target,	verifier));
		FOR_EACH_VERIFIER(new TextureLevelSizeCase				(m_context, ("red_size" + verifierSuffix).c_str(),					"Verify TEXTURE_RED_SIZE",					textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_RED_SIZE));
		FOR_EACH_VERIFIER(new TextureLevelSizeCase				(m_context, ("green_size" + verifierSuffix).c_str(),				"Verify TEXTURE_GREEN_SIZE",				textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_GREEN_SIZE));
		FOR_EACH_VERIFIER(new TextureLevelSizeCase				(m_context, ("blue_size" + verifierSuffix).c_str(),					"Verify TEXTURE_BLUE_SIZE",					textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_BLUE_SIZE));
		FOR_EACH_VERIFIER(new TextureLevelSizeCase				(m_context, ("alpha_size" + verifierSuffix).c_str(),				"Verify TEXTURE_ALPHA_SIZE",				textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_ALPHA_SIZE));
		FOR_EACH_VERIFIER(new TextureLevelSizeCase				(m_context, ("depth_size" + verifierSuffix).c_str(),				"Verify TEXTURE_DEPTH_SIZE",				textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_DEPTH_SIZE));
		FOR_EACH_VERIFIER(new TextureLevelSizeCase				(m_context, ("stencil_size" + verifierSuffix).c_str(),				"Verify TEXTURE_STENCIL_SIZE",				textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_STENCIL_SIZE));
		FOR_EACH_VERIFIER(new TextureLevelSizeCase				(m_context, ("shared_size" + verifierSuffix).c_str(),				"Verify TEXTURE_SHARED_SIZE",				textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_SHARED_SIZE));
		FOR_EACH_VERIFIER(new TextureLevelTypeCase				(m_context, ("red_type" + verifierSuffix).c_str(),					"Verify TEXTURE_RED_TYPE",					textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_RED_TYPE));
		FOR_EACH_VERIFIER(new TextureLevelTypeCase				(m_context, ("green_type" + verifierSuffix).c_str(),				"Verify TEXTURE_GREEN_TYPE",				textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_GREEN_TYPE));
		FOR_EACH_VERIFIER(new TextureLevelTypeCase				(m_context, ("blue_type" + verifierSuffix).c_str(),					"Verify TEXTURE_BLUE_TYPE",					textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_BLUE_TYPE));
		FOR_EACH_VERIFIER(new TextureLevelTypeCase				(m_context, ("alpha_type" + verifierSuffix).c_str(),				"Verify TEXTURE_ALPHA_TYPE",				textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_ALPHA_TYPE));
		FOR_EACH_VERIFIER(new TextureLevelTypeCase				(m_context, ("depth_type" + verifierSuffix).c_str(),				"Verify TEXTURE_DEPTH_TYPE",				textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_DEPTH_TYPE));
		FOR_EACH_VERIFIER(new TextureLevelCompressedCase		(m_context, ("compressed" + verifierSuffix).c_str(),				"Verify TEXTURE_COMPRESSED",				textureTargets[targetNdx].target,	verifier));
		FOR_EACH_VERIFIER(new TextureLevelBufferDataStoreCase	(m_context, ("buffer_data_store_binding" + verifierSuffix).c_str(),	"Verify TEXTURE_BUFFER_DATA_STORE_BINDING",	textureTargets[targetNdx].target,	verifier));
		FOR_EACH_VERIFIER(new TextureLevelBufferDataOffsetCase	(m_context, ("buffer_offset" + verifierSuffix).c_str(),				"Verify TEXTURE_BUFFER_OFFSET",				textureTargets[targetNdx].target,	verifier));
		FOR_EACH_VERIFIER(new TextureLevelBufferDataSizeCase	(m_context, ("buffer_size" + verifierSuffix).c_str(),				"Verify TEXTURE_BUFFER_SIZE",				textureTargets[targetNdx].target,	verifier));
	}

#undef FOR_EACH_VERIFIER
}

} // Functional
} // gles31
} // deqp
