Home | History | Annotate | Download | only in functional
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES 3.1 Module
      3  * -------------------------------------------------
      4  *
      5  * Copyright 2014 The Android Open Source Project
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  *
     19  *//*!
     20  * \file
     21  * \brief Texture level state query tests
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es31fTextureLevelStateQueryTests.hpp"
     25 #include "glsStateQueryUtil.hpp"
     26 #include "tcuTestLog.hpp"
     27 #include "gluRenderContext.hpp"
     28 #include "gluCallLogWrapper.hpp"
     29 #include "gluTextureUtil.hpp"
     30 #include "gluStrUtil.hpp"
     31 #include "gluContextInfo.hpp"
     32 #include "glwFunctions.hpp"
     33 #include "glwEnums.hpp"
     34 #include "tcuTextureUtil.hpp"
     35 #include "tcuFormatUtil.hpp"
     36 #include "deStringUtil.hpp"
     37 #include "deUniquePtr.hpp"
     38 
     39 namespace deqp
     40 {
     41 namespace gles31
     42 {
     43 namespace Functional
     44 {
     45 namespace
     46 {
     47 
     48 using namespace gls::StateQueryUtil;
     49 
     50 
     51 static bool textureTypeHasDepth (glw::GLenum textureBindTarget)
     52 {
     53 	switch (textureBindTarget)
     54 	{
     55 		case GL_TEXTURE_2D:						return false;
     56 		case GL_TEXTURE_3D:						return true;
     57 		case GL_TEXTURE_2D_ARRAY:				return true;
     58 		case GL_TEXTURE_CUBE_MAP:				return false;
     59 		case GL_TEXTURE_2D_MULTISAMPLE:			return false;
     60 		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:	return true;
     61 		case GL_TEXTURE_BUFFER:					return false;
     62 		case GL_TEXTURE_CUBE_MAP_ARRAY:			return true;
     63 		default:
     64 			DE_ASSERT(DE_FALSE);
     65 			return false;
     66 	}
     67 }
     68 
     69 static bool textureTypeHasHeight (glw::GLenum textureBindTarget)
     70 {
     71 	switch (textureBindTarget)
     72 	{
     73 		case GL_TEXTURE_2D:						return true;
     74 		case GL_TEXTURE_3D:						return true;
     75 		case GL_TEXTURE_2D_ARRAY:				return true;
     76 		case GL_TEXTURE_CUBE_MAP:				return true;
     77 		case GL_TEXTURE_2D_MULTISAMPLE:			return true;
     78 		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:	return true;
     79 		case GL_TEXTURE_BUFFER:					return false;
     80 		case GL_TEXTURE_CUBE_MAP_ARRAY:			return true;
     81 		default:
     82 			DE_ASSERT(DE_FALSE);
     83 			return false;
     84 	}
     85 }
     86 
     87 static const char* getTextureTargetExtension (glw::GLenum target)
     88 {
     89 	switch (target)
     90 	{
     91 		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:	return "GL_OES_texture_storage_multisample_2d_array";
     92 		case GL_TEXTURE_BUFFER:					return "GL_EXT_texture_buffer";
     93 		case GL_TEXTURE_CUBE_MAP_ARRAY:			return "GL_EXT_texture_cube_map_array";
     94 		default:
     95 			DE_ASSERT(DE_FALSE);
     96 			return DE_NULL;
     97 	}
     98 }
     99 
    100 static bool isCoreTextureTarget (glw::GLenum target, const glu::ContextType& contextType)
    101 {
    102 	switch (target)
    103 	{
    104 		case GL_TEXTURE_2D:
    105 		case GL_TEXTURE_3D:
    106 		case GL_TEXTURE_2D_ARRAY:
    107 		case GL_TEXTURE_CUBE_MAP:
    108 		case GL_TEXTURE_2D_MULTISAMPLE:
    109 			return true;
    110 
    111 		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
    112 		case GL_TEXTURE_BUFFER:
    113 		case GL_TEXTURE_CUBE_MAP_ARRAY:
    114 			return glu::contextSupports(contextType, glu::ApiType::es(3, 2));
    115 
    116 		default:
    117 			return false;
    118 	}
    119 }
    120 
    121 struct TextureGenerationSpec
    122 {
    123 	struct TextureLevelSpec
    124 	{
    125 		int			width;
    126 		int			height;
    127 		int			depth;
    128 		int			level;
    129 		glw::GLenum internalFormat;
    130 		bool		compressed;
    131 
    132 		TextureLevelSpec (void)
    133 			: width				(0)
    134 			, height			(0)
    135 			, depth				(0)
    136 			, level				(0)
    137 			, internalFormat	(GL_RGBA)
    138 			, compressed		(false)
    139 		{
    140 		}
    141 	};
    142 
    143 	glw::GLenum						bindTarget;
    144 	glw::GLenum						queryTarget;
    145 	bool							immutable;
    146 	bool							fixedSamplePos;	// !< fixed sample pos argument for multisample textures
    147 	int								sampleCount;
    148 	int								texBufferDataOffset;
    149 	int								texBufferDataSize;
    150 	bool							bindWholeArray;
    151 	std::vector<TextureLevelSpec>	levels;
    152 	std::string						description;
    153 
    154 	TextureGenerationSpec (void)
    155 		: immutable				(true)
    156 		, fixedSamplePos		(true)
    157 		, sampleCount			(0)
    158 		, texBufferDataOffset	(0)
    159 		, texBufferDataSize		(256)
    160 		, bindWholeArray		(false)
    161 	{
    162 	}
    163 };
    164 struct IntegerPrinter
    165 {
    166 	static std::string	getIntegerName	(int v)		{ return de::toString(v); }
    167 	static std::string	getFloatName	(float v)	{ return de::toString(v); }
    168 };
    169 
    170 struct PixelFormatPrinter
    171 {
    172 	static std::string	getIntegerName	(int v)		{ return de::toString(glu::getTextureFormatStr(v));		}
    173 	static std::string	getFloatName	(float v)	{ return de::toString(glu::getTextureFormatStr((int)v));	}
    174 };
    175 
    176 template <typename Printer>
    177 static bool verifyTextureLevelParameterEqualWithPrinter (glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, int refValue, QueryType type)
    178 {
    179 	QueriedState			state;
    180 	tcu::ResultCollector	result	(gl.getLog(), " // ERROR: ");
    181 
    182 	gl.getLog() << tcu::TestLog::Message << "Verifying " << glu::getTextureLevelParameterStr(pname) << ", expecting " << Printer::getIntegerName(refValue) << tcu::TestLog::EndMessage;
    183 	queryTextureLevelState(result, gl, type, target, level, pname, state);
    184 
    185 	if (state.isUndefined())
    186 		return false;
    187 
    188 	verifyInteger(result, state, refValue);
    189 
    190 	return result.getResult() == QP_TEST_RESULT_PASS;
    191 }
    192 
    193 static bool verifyTextureLevelParameterEqual (glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, int refValue, QueryType type)
    194 {
    195 	return verifyTextureLevelParameterEqualWithPrinter<IntegerPrinter>(gl, target, level, pname, refValue, type);
    196 }
    197 
    198 static bool verifyTextureLevelParameterInternalFormatEqual (glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, int refValue, QueryType type)
    199 {
    200 	return verifyTextureLevelParameterEqualWithPrinter<PixelFormatPrinter>(gl, target, level, pname, refValue, type);
    201 }
    202 
    203 static bool verifyTextureLevelParameterGreaterOrEqual (glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, int refValue, QueryType type)
    204 {
    205 	QueriedState			state;
    206 	tcu::ResultCollector	result	(gl.getLog(), " // ERROR: ");
    207 
    208 	gl.getLog() << tcu::TestLog::Message << "Verifying " << glu::getTextureLevelParameterStr(pname) << ", expecting " << refValue << " or greater" << tcu::TestLog::EndMessage;
    209 	queryTextureLevelState(result, gl, type, target, level, pname, state);
    210 
    211 	if (state.isUndefined())
    212 		return false;
    213 
    214 	verifyIntegerMin(result, state, refValue);
    215 
    216 	return result.getResult() == QP_TEST_RESULT_PASS;
    217 }
    218 
    219 static bool verifyTextureLevelParameterInternalFormatAnyOf (glu::CallLogWrapper& gl, glw::GLenum target, int level, glw::GLenum pname, const int* refValues, int numRefValues, QueryType type)
    220 {
    221 	QueriedState			state;
    222 	tcu::ResultCollector	result	(gl.getLog(), " // ERROR: ");
    223 
    224 	// Log what we try to do
    225 	{
    226 		tcu::MessageBuilder msg(&gl.getLog());
    227 
    228 		msg << "Verifying " << glu::getTextureLevelParameterStr(pname) << ", expecting any of {";
    229 		for (int ndx = 0; ndx < numRefValues; ++ndx)
    230 		{
    231 			if (ndx != 0)
    232 				msg << ", ";
    233 			msg << glu::getTextureFormatStr(refValues[ndx]);
    234 		}
    235 		msg << "}";
    236 		msg << tcu::TestLog::EndMessage;
    237 	}
    238 
    239 	queryTextureLevelState(result, gl, type, target, level, pname, state);
    240 	if (state.isUndefined())
    241 		return false;
    242 
    243 	// verify
    244 	switch (state.getType())
    245 	{
    246 		case DATATYPE_INTEGER:
    247 		{
    248 			for (int ndx = 0; ndx < numRefValues; ++ndx)
    249 				if (state.getIntAccess() == refValues[ndx])
    250 					return true;
    251 
    252 			gl.getLog() << tcu::TestLog::Message << "Error: got " << state.getIntAccess() << ", (" << glu::getTextureFormatStr(state.getIntAccess()) << ")" << tcu::TestLog::EndMessage;
    253 			return false;
    254 		}
    255 		case DATATYPE_FLOAT:
    256 		{
    257 			for (int ndx = 0; ndx < numRefValues; ++ndx)
    258 				if (state.getFloatAccess() == (float)refValues[ndx])
    259 					return true;
    260 
    261 			gl.getLog() << tcu::TestLog::Message << "Error: got " << state.getFloatAccess() << ", (" << glu::getTextureFormatStr((int)state.getFloatAccess()) << ")" << tcu::TestLog::EndMessage;
    262 			return false;
    263 		}
    264 		default:
    265 			DE_ASSERT(DE_FALSE);
    266 			return false;
    267 	}
    268 }
    269 
    270 static bool isDepthFormat (const tcu::TextureFormat& fmt)
    271 {
    272 	return fmt.order == tcu::TextureFormat::D || fmt.order == tcu::TextureFormat::DS;
    273 }
    274 
    275 static bool isColorRenderableFormat (glw::GLenum internalFormat)
    276 {
    277 	return	internalFormat == GL_RGB565			||
    278 			internalFormat == GL_RGBA4			||
    279 			internalFormat == GL_RGB5_A1		||
    280 			internalFormat == GL_RGB10_A2		||
    281 			internalFormat == GL_RGB10_A2UI		||
    282 			internalFormat == GL_SRGB8_ALPHA8	||
    283 			internalFormat == GL_R8				||
    284 			internalFormat == GL_RG8			||
    285 			internalFormat == GL_RGB8			||
    286 			internalFormat == GL_RGBA8			||
    287 			internalFormat == GL_R8I			||
    288 			internalFormat == GL_RG8I			||
    289 			internalFormat == GL_RGBA8I			||
    290 			internalFormat == GL_R8UI			||
    291 			internalFormat == GL_RG8UI			||
    292 			internalFormat == GL_RGBA8UI		||
    293 			internalFormat == GL_R16I			||
    294 			internalFormat == GL_RG16I			||
    295 			internalFormat == GL_RGBA16I		||
    296 			internalFormat == GL_R16UI			||
    297 			internalFormat == GL_RG16UI			||
    298 			internalFormat == GL_RGBA16UI		||
    299 			internalFormat == GL_R32I			||
    300 			internalFormat == GL_RG32I			||
    301 			internalFormat == GL_RGBA32I		||
    302 			internalFormat == GL_R32UI			||
    303 			internalFormat == GL_RG32UI			||
    304 			internalFormat == GL_RGBA32UI;
    305 }
    306 
    307 static bool isRenderableFormat (glw::GLenum internalFormat)
    308 {
    309 	return	isColorRenderableFormat(internalFormat)	||
    310 			internalFormat == GL_DEPTH_COMPONENT16	||
    311 			internalFormat == GL_DEPTH_COMPONENT24	||
    312 			internalFormat == GL_DEPTH_COMPONENT32F	||
    313 			internalFormat == GL_DEPTH24_STENCIL8	||
    314 			internalFormat == GL_DEPTH32F_STENCIL8;
    315 }
    316 
    317 static bool isTextureBufferFormat (glw::GLenum internalFormat)
    318 {
    319 	return	internalFormat == GL_R8			||
    320 			internalFormat == GL_R16F		||
    321 			internalFormat == GL_R32F		||
    322 			internalFormat == GL_R8I		||
    323 			internalFormat == GL_R16I		||
    324 			internalFormat == GL_R32I		||
    325 			internalFormat == GL_R8UI		||
    326 			internalFormat == GL_R16UI		||
    327 			internalFormat == GL_R32UI		||
    328 			internalFormat == GL_RG8		||
    329 			internalFormat == GL_RG16F		||
    330 			internalFormat == GL_RG32F		||
    331 			internalFormat == GL_RG8I		||
    332 			internalFormat == GL_RG16I		||
    333 			internalFormat == GL_RG32I		||
    334 			internalFormat == GL_RG8UI		||
    335 			internalFormat == GL_RG16UI		||
    336 			internalFormat == GL_RG32UI		||
    337 			internalFormat == GL_RGB32F		||
    338 			internalFormat == GL_RGB32I		||
    339 			internalFormat == GL_RGB32UI	||
    340 			internalFormat == GL_RGBA8		||
    341 			internalFormat == GL_RGBA16F	||
    342 			internalFormat == GL_RGBA32F	||
    343 			internalFormat == GL_RGBA8I		||
    344 			internalFormat == GL_RGBA16I	||
    345 			internalFormat == GL_RGBA32I	||
    346 			internalFormat == GL_RGBA8UI	||
    347 			internalFormat == GL_RGBA16UI	||
    348 			internalFormat == GL_RGBA32UI;
    349 }
    350 
    351 static bool isLegalFormatForTarget (glw::GLenum target, glw::GLenum format)
    352 {
    353 	const tcu::TextureFormat fmt = glu::mapGLInternalFormat(format);
    354 
    355 	if (target == GL_TEXTURE_3D && isDepthFormat(fmt))
    356 		return false;
    357 	if ((target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY) && !isRenderableFormat(format))
    358 		return false;
    359 	if (target == GL_TEXTURE_BUFFER || !isTextureBufferFormat(format))
    360 		return false;
    361 	return true;
    362 }
    363 
    364 static bool isCompressionSupportedForTarget (glw::GLenum target)
    365 {
    366 	return target == GL_TEXTURE_2D || target == GL_TEXTURE_2D_ARRAY;
    367 }
    368 
    369 static bool isMultisampleTarget (glw::GLenum target)
    370 {
    371 	return target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
    372 }
    373 
    374 static bool targetSupportsMipLevels (glw::GLenum target)
    375 {
    376 	return	target != GL_TEXTURE_2D_MULTISAMPLE &&
    377 			target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY &&
    378 			target != GL_TEXTURE_BUFFER;
    379 }
    380 
    381 static int getPixelSize (glw::GLenum internalFormat)
    382 {
    383 	const tcu::TextureFormat fmt = glu::mapGLInternalFormat(internalFormat);
    384 	return fmt.getPixelSize();
    385 }
    386 
    387 static void generateColorTextureGenerationGroup (std::vector<TextureGenerationSpec>& group, glw::GLenum target, int maxSamples, glw::GLenum internalFormat)
    388 {
    389 	const glw::GLenum queryTarget = (target == GL_TEXTURE_CUBE_MAP) ? (GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) : (target);
    390 
    391 	// initial
    392 	{
    393 		TextureGenerationSpec texGen;
    394 		texGen.bindTarget		= target;
    395 		texGen.queryTarget		= queryTarget;
    396 		texGen.immutable		= true;
    397 		texGen.sampleCount		= 0;
    398 		texGen.description		= glu::getTextureTargetStr(target).toString() + ", initial values";
    399 
    400 		group.push_back(texGen);
    401 	}
    402 
    403 	// ms targets
    404 	if (isMultisampleTarget(target))
    405 	{
    406 		{
    407 			TextureGenerationSpec					texGen;
    408 			TextureGenerationSpec::TextureLevelSpec	level;
    409 
    410 			texGen.bindTarget		= target;
    411 			texGen.queryTarget		= queryTarget;
    412 			texGen.immutable		= true;
    413 			texGen.sampleCount		= 1;
    414 			texGen.fixedSamplePos	= false;
    415 			texGen.description		= glu::getTextureTargetStr(target).toString() + ", low sample count";
    416 
    417 			level.width				= 16;
    418 			level.height			= 16;
    419 			level.depth				= (textureTypeHasDepth(texGen.bindTarget)) ? (6) : (1);
    420 			level.level				= 0;
    421 			level.internalFormat	= internalFormat;
    422 			level.compressed		= false;
    423 
    424 			texGen.levels.push_back(level);
    425 			group.push_back(texGen);
    426 		}
    427 		{
    428 			TextureGenerationSpec					texGen;
    429 			TextureGenerationSpec::TextureLevelSpec	level;
    430 
    431 			texGen.bindTarget		= target;
    432 			texGen.queryTarget		= queryTarget;
    433 			texGen.immutable		= true;
    434 			texGen.sampleCount		= maxSamples;
    435 			texGen.fixedSamplePos	= false;
    436 			texGen.description		= glu::getTextureTargetStr(target).toString() + ", high sample count";
    437 
    438 			level.width				= 32;
    439 			level.height			= 32;
    440 			level.depth				= (textureTypeHasDepth(texGen.bindTarget)) ? (6) : (1);
    441 			level.level				= 0;
    442 			level.internalFormat	= internalFormat;
    443 			level.compressed		= false;
    444 
    445 			texGen.levels.push_back(level);
    446 			group.push_back(texGen);
    447 		}
    448 		{
    449 			TextureGenerationSpec					texGen;
    450 			TextureGenerationSpec::TextureLevelSpec	level;
    451 
    452 			texGen.bindTarget		= target;
    453 			texGen.queryTarget		= queryTarget;
    454 			texGen.immutable		= true;
    455 			texGen.sampleCount		= maxSamples;
    456 			texGen.fixedSamplePos	= true;
    457 			texGen.description		= glu::getTextureTargetStr(target).toString() + ", fixed sample positions";
    458 
    459 			level.width				= 32;
    460 			level.height			= 32;
    461 			level.depth				= (textureTypeHasDepth(texGen.bindTarget)) ? (6) : (1);
    462 			level.level				= 0;
    463 			level.internalFormat	= internalFormat;
    464 			level.compressed		= false;
    465 
    466 			texGen.levels.push_back(level);
    467 			group.push_back(texGen);
    468 		}
    469 	}
    470 	else if (target == GL_TEXTURE_BUFFER)
    471 	{
    472 		// whole buffer
    473 		{
    474 			TextureGenerationSpec					texGen;
    475 			TextureGenerationSpec::TextureLevelSpec	level;
    476 			const int								baseSize = getPixelSize(internalFormat);
    477 
    478 			texGen.bindTarget			= target;
    479 			texGen.queryTarget			= queryTarget;
    480 			texGen.immutable			= true;
    481 			texGen.description			= glu::getTextureTargetStr(target).toString() + ", whole buffer";
    482 			texGen.texBufferDataOffset	= 0;
    483 			texGen.texBufferDataSize	= 32 * baseSize + (baseSize - 1);
    484 			texGen.bindWholeArray		= true;
    485 
    486 			level.width				= 32;
    487 			level.height			= 1;
    488 			level.depth				= 1;
    489 			level.level				= 0;
    490 			level.internalFormat	= internalFormat;
    491 			level.compressed		= false;
    492 
    493 			texGen.levels.push_back(level);
    494 			group.push_back(texGen);
    495 		}
    496 		// partial buffer
    497 		{
    498 			TextureGenerationSpec					texGen;
    499 			TextureGenerationSpec::TextureLevelSpec	level;
    500 			const int								baseSize = getPixelSize(internalFormat);
    501 
    502 			texGen.bindTarget			= target;
    503 			texGen.queryTarget			= queryTarget;
    504 			texGen.immutable			= true;
    505 			texGen.description			= glu::getTextureTargetStr(target).toString() + ", partial buffer";
    506 			texGen.texBufferDataOffset	= 256;
    507 			texGen.texBufferDataSize	= 16 * baseSize + (baseSize - 1);
    508 			texGen.bindWholeArray		= false;
    509 
    510 			level.width				= 16;
    511 			level.height			= 1;
    512 			level.depth				= 1;
    513 			level.level				= 0;
    514 			level.internalFormat	= internalFormat;
    515 			level.compressed		= false;
    516 
    517 			texGen.levels.push_back(level);
    518 			group.push_back(texGen);
    519 		}
    520 	}
    521 	else
    522 	{
    523 		// immutable
    524 		{
    525 			TextureGenerationSpec					texGen;
    526 			TextureGenerationSpec::TextureLevelSpec	level;
    527 
    528 			texGen.bindTarget		= target;
    529 			texGen.queryTarget		= queryTarget;
    530 			texGen.immutable		= true;
    531 			texGen.description		= glu::getTextureTargetStr(target).toString() + ", immutable";
    532 
    533 			level.width				= 32;
    534 			level.height			= 32;
    535 			level.depth				= (textureTypeHasDepth(texGen.bindTarget)) ? (6) : (1);
    536 			level.level				= 0;
    537 			level.internalFormat	= internalFormat;
    538 			level.compressed		= false;
    539 
    540 			texGen.levels.push_back(level);
    541 			group.push_back(texGen);
    542 		}
    543 		// mutable
    544 		{
    545 			TextureGenerationSpec					texGen;
    546 			TextureGenerationSpec::TextureLevelSpec	level;
    547 
    548 			texGen.bindTarget		= target;
    549 			texGen.queryTarget		= queryTarget;
    550 			texGen.immutable		= false;
    551 			texGen.description		= glu::getTextureTargetStr(target).toString() + ", mutable";
    552 
    553 			level.width				= 16;
    554 			level.height			= (target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) ? (16) : (64);
    555 			level.depth				= (textureTypeHasDepth(texGen.bindTarget)) ? (6) : (1);
    556 			level.level				= 0;
    557 			level.internalFormat	= internalFormat;
    558 			level.compressed		= false;
    559 
    560 			texGen.levels.push_back(level);
    561 			group.push_back(texGen);
    562 		}
    563 		// mip3
    564 		{
    565 			TextureGenerationSpec					texGen;
    566 			TextureGenerationSpec::TextureLevelSpec	level;
    567 
    568 			texGen.bindTarget		= target;
    569 			texGen.queryTarget		= queryTarget;
    570 			texGen.immutable		= false;
    571 			texGen.description		= glu::getTextureTargetStr(target).toString() + ", mip level 3";
    572 
    573 			level.width				= 4;
    574 			level.height			= (target == GL_TEXTURE_CUBE_MAP || target == GL_TEXTURE_CUBE_MAP_ARRAY) ? (4) : (8);
    575 			level.depth				= (textureTypeHasDepth(texGen.bindTarget)) ? (6) : (1);
    576 			level.level				= 3;
    577 			level.internalFormat	= internalFormat;
    578 			level.compressed		= false;
    579 
    580 			texGen.levels.push_back(level);
    581 			group.push_back(texGen);
    582 		}
    583 	}
    584 }
    585 
    586 static void generateInternalFormatTextureGenerationGroup (std::vector<TextureGenerationSpec>& group, glw::GLenum target)
    587 {
    588 	const glw::GLenum queryTarget = (target == GL_TEXTURE_CUBE_MAP) ? (GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) : (target);
    589 
    590 	// Internal formats
    591 	static const glw::GLenum internalFormats[] =
    592 	{
    593 		GL_R8, GL_R8_SNORM, GL_RG8, GL_RG8_SNORM, GL_RGB8, GL_RGB8_SNORM, GL_RGB565, GL_RGBA4, GL_RGB5_A1,
    594 		GL_RGBA8, GL_RGBA8_SNORM, GL_RGB10_A2, GL_RGB10_A2UI, GL_SRGB8, GL_SRGB8_ALPHA8, GL_R16F, GL_RG16F,
    595 		GL_RGB16F, GL_RGBA16F, GL_R32F, GL_RG32F, GL_RGB32F, GL_RGBA32F, GL_R11F_G11F_B10F, GL_RGB9_E5, GL_R8I,
    596 		GL_R8UI, GL_R16I, GL_R16UI, GL_R32I, GL_R32UI, GL_RG8I, GL_RG8UI, GL_RG16I, GL_RG16UI, GL_RG32I, GL_RG32UI,
    597 		GL_RGB8I, GL_RGB8UI, GL_RGB16I, GL_RGB16UI, GL_RGB32I, GL_RGB32UI, GL_RGBA8I, GL_RGBA8UI, GL_RGBA16I,
    598 		GL_RGBA16UI, GL_RGBA32I, GL_RGBA32UI,
    599 
    600 		GL_DEPTH_COMPONENT32F, GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT16,
    601 		GL_DEPTH32F_STENCIL8, GL_DEPTH24_STENCIL8
    602 	};
    603 
    604 	// initial
    605 	{
    606 		TextureGenerationSpec texGen;
    607 		texGen.bindTarget		= target;
    608 		texGen.queryTarget		= queryTarget;
    609 		texGen.immutable		= true;
    610 		texGen.sampleCount		= 0;
    611 		texGen.fixedSamplePos	= true;
    612 		texGen.description		= glu::getTextureTargetStr(target).toString() + ", initial values";
    613 
    614 		group.push_back(texGen);
    615 	}
    616 
    617 	// test all formats
    618 	for (int internalFormatNdx = 0; internalFormatNdx < DE_LENGTH_OF_ARRAY(internalFormats); ++internalFormatNdx)
    619 	{
    620 		if (!isLegalFormatForTarget(target, internalFormats[internalFormatNdx]))
    621 			continue;
    622 
    623 		const int								baseSize = getPixelSize(internalFormats[internalFormatNdx]);
    624 		TextureGenerationSpec					texGen;
    625 		TextureGenerationSpec::TextureLevelSpec	level;
    626 
    627 		texGen.bindTarget		= target;
    628 		texGen.queryTarget		= queryTarget;
    629 		texGen.immutable		= true;
    630 		texGen.sampleCount		= (isMultisampleTarget(target) ? (1) : (0));
    631 		texGen.description		= glu::getTextureTargetStr(target).toString() + ", internal format " + glu::getTextureFormatName(internalFormats[internalFormatNdx]);
    632 
    633 		if (target == GL_TEXTURE_BUFFER)
    634 		{
    635 			texGen.texBufferDataOffset	= 0;
    636 			texGen.texBufferDataSize	= 32 * baseSize + (baseSize - 1);
    637 			texGen.bindWholeArray		= true;
    638 		}
    639 
    640 		level.width				= 32;
    641 		level.height			= (textureTypeHasHeight(target)) ? (32) : (1);
    642 		level.depth				= (textureTypeHasDepth(target)) ? (6) : (1);
    643 		level.level				= 0;
    644 		level.internalFormat	= internalFormats[internalFormatNdx];
    645 		level.compressed		= false;
    646 
    647 		texGen.levels.push_back(level);
    648 		group.push_back(texGen);
    649 	}
    650 
    651 	// test mutable rgba8 with mip level 3
    652 	if (targetSupportsMipLevels(target))
    653 	{
    654 		TextureGenerationSpec					texGen;
    655 		TextureGenerationSpec::TextureLevelSpec	level;
    656 
    657 		texGen.bindTarget		= target;
    658 		texGen.queryTarget		= queryTarget;
    659 		texGen.immutable		= false;
    660 		texGen.description		= glu::getTextureTargetStr(target).toString() + ", internal format GL_RGBA8, mip level 3";
    661 
    662 		level.width				= 32;
    663 		level.height			= 32;
    664 		level.depth				= (textureTypeHasDepth(target)) ? (6) : (1);
    665 		level.level				= 3;
    666 		level.internalFormat	= GL_RGBA8;
    667 		level.compressed		= false;
    668 
    669 		texGen.levels.push_back(level);
    670 		group.push_back(texGen);
    671 	}
    672 }
    673 
    674 static void generateCompressedTextureGenerationGroup (std::vector<TextureGenerationSpec>& group, glw::GLenum target)
    675 {
    676 	const glw::GLenum queryTarget = (target == GL_TEXTURE_CUBE_MAP) ? (GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) : (target);
    677 
    678 	// initial
    679 	{
    680 		TextureGenerationSpec texGen;
    681 		texGen.bindTarget	= target;
    682 		texGen.queryTarget	= queryTarget;
    683 		texGen.immutable	= true;
    684 		texGen.description	= glu::getTextureTargetStr(target).toString() + ", initial values";
    685 
    686 		group.push_back(texGen);
    687 	}
    688 
    689 	// compressed
    690 	if (isCompressionSupportedForTarget(target))
    691 	{
    692 		TextureGenerationSpec					texGen;
    693 		TextureGenerationSpec::TextureLevelSpec	level;
    694 
    695 		texGen.bindTarget		= target;
    696 		texGen.queryTarget		= queryTarget;
    697 		texGen.immutable		= false;
    698 		texGen.description		= glu::getTextureTargetStr(target).toString() + ", compressed";
    699 
    700 		level.width				= 32;
    701 		level.height			= 32;
    702 		level.depth				= (target == GL_TEXTURE_2D_ARRAY) ? (2) : (1);
    703 		level.level				= 0;
    704 		level.internalFormat	= GL_COMPRESSED_RGB8_ETC2;
    705 		level.compressed		= true;
    706 
    707 		texGen.levels.push_back(level);
    708 		group.push_back(texGen);
    709 	}
    710 }
    711 
    712 static void generateTextureBufferGenerationGroup (std::vector<TextureGenerationSpec>& group, glw::GLenum target)
    713 {
    714 	const glw::GLenum queryTarget = (target == GL_TEXTURE_CUBE_MAP) ? (GL_TEXTURE_CUBE_MAP_NEGATIVE_Y) : (target);
    715 
    716 	// initial
    717 	{
    718 		TextureGenerationSpec texGen;
    719 		texGen.bindTarget		= target;
    720 		texGen.queryTarget		= queryTarget;
    721 		texGen.immutable		= true;
    722 		texGen.sampleCount		= 0;
    723 		texGen.description		= glu::getTextureTargetStr(target).toString() + ", initial values";
    724 
    725 		group.push_back(texGen);
    726 	}
    727 
    728 	// actual specification tests are in texture_buffer tests, no need to do them here too
    729 }
    730 
    731 bool applyTextureGenerationSpec (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec, glw::GLuint& texBuffer)
    732 {
    733 	bool allOk = true;
    734 
    735 	DE_ASSERT(!(spec.immutable && spec.levels.size() > 1));		// !< immutable textures have only one level
    736 
    737 	for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx)
    738 	{
    739 		const glu::TransferFormat transferFormat = (spec.levels[levelNdx].compressed) ? (glu::TransferFormat()) : (glu::getTransferFormat(glu::mapGLInternalFormat(spec.levels[levelNdx].internalFormat)));
    740 
    741 		if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D)
    742 			gl.glTexStorage2D(spec.bindTarget, 1, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height);
    743 		else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_3D)
    744 			gl.glTexStorage3D(spec.bindTarget, 1, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, spec.levels[levelNdx].depth);
    745 		else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D_ARRAY)
    746 			gl.glTexStorage3D(spec.bindTarget, 1, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, spec.levels[levelNdx].depth);
    747 		else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_CUBE_MAP)
    748 			gl.glTexStorage2D(spec.bindTarget, 1, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height);
    749 		else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D_MULTISAMPLE)
    750 			gl.glTexStorage2DMultisample(spec.bindTarget, spec.sampleCount, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, (spec.fixedSamplePos) ? (GL_TRUE) : (GL_FALSE));
    751 		else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)
    752 			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));
    753 		else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_CUBE_MAP_ARRAY)
    754 			gl.glTexStorage3D(spec.bindTarget, 1, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, spec.levels[levelNdx].depth);
    755 		else if (!spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D)
    756 			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);
    757 		else if (!spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_3D)
    758 			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);
    759 		else if (!spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D_ARRAY)
    760 			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);
    761 		else if (!spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_CUBE_MAP)
    762 			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);
    763 		else if (!spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_CUBE_MAP_ARRAY)
    764 			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);
    765 		else if (!spec.immutable && spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D)
    766 		{
    767 			DE_ASSERT(spec.levels[levelNdx].width == 32);
    768 			DE_ASSERT(spec.levels[levelNdx].height == 32);
    769 			DE_ASSERT(spec.levels[levelNdx].internalFormat == GL_COMPRESSED_RGB8_ETC2);
    770 
    771 			static const deUint8 buffer[64 * 8] = { 0 };
    772 			gl.glCompressedTexImage2D(spec.bindTarget, spec.levels[levelNdx].level, spec.levels[levelNdx].internalFormat, spec.levels[levelNdx].width, spec.levels[levelNdx].height, 0, sizeof(buffer), buffer);
    773 		}
    774 		else if (!spec.immutable && spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_2D_ARRAY)
    775 		{
    776 			DE_ASSERT(spec.levels[levelNdx].width == 32);
    777 			DE_ASSERT(spec.levels[levelNdx].height == 32);
    778 			DE_ASSERT(spec.levels[levelNdx].depth == 2);
    779 			DE_ASSERT(spec.levels[levelNdx].internalFormat == GL_COMPRESSED_RGB8_ETC2);
    780 
    781 			static const deUint8 buffer[64 * 8 * 2] = { 0 };
    782 			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);
    783 		}
    784 		else if (spec.immutable && !spec.levels[levelNdx].compressed && spec.bindTarget == GL_TEXTURE_BUFFER)
    785 		{
    786 			gl.glGenBuffers(1, &texBuffer);
    787 			gl.glBindBuffer(GL_TEXTURE_BUFFER, texBuffer);
    788 
    789 			if (spec.bindWholeArray)
    790 			{
    791 				gl.glBufferData(GL_TEXTURE_BUFFER, spec.texBufferDataSize, DE_NULL, GL_STATIC_DRAW);
    792 				gl.glTexBuffer(GL_TEXTURE_BUFFER, spec.levels[levelNdx].internalFormat, texBuffer);
    793 			}
    794 			else
    795 			{
    796 				gl.glBufferData(GL_TEXTURE_BUFFER, spec.texBufferDataOffset + spec.texBufferDataSize, DE_NULL, GL_STATIC_DRAW);
    797 				gl.glTexBufferRange(GL_TEXTURE_BUFFER, spec.levels[levelNdx].internalFormat, texBuffer, spec.texBufferDataOffset, spec.texBufferDataSize);
    798 			}
    799 		}
    800 		else
    801 			DE_ASSERT(DE_FALSE);
    802 
    803 		{
    804 			const glw::GLenum err = gl.glGetError();
    805 			if (err != GL_NO_ERROR)
    806 			{
    807 				gl.getLog()	<< tcu::TestLog::Message
    808 							<< "Texture specification failed, got " + glu::getErrorStr(err).toString()
    809 							<< tcu::TestLog::EndMessage;
    810 				allOk = false;
    811 			}
    812 		}
    813 	}
    814 
    815 	return allOk;
    816 }
    817 
    818 class TextureLevelCase : public TestCase
    819 {
    820 public:
    821 										TextureLevelCase		(Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type);
    822 										~TextureLevelCase		(void);
    823 
    824 	void								init					(void);
    825 	void								deinit					(void);
    826 	IterateResult						iterate					(void);
    827 
    828 protected:
    829 	void								getFormatSamples		(glw::GLenum internalFormat, std::vector<int>& samples);
    830 	bool								testConfig				(const TextureGenerationSpec& spec);
    831 	virtual bool						checkTextureState		(glu::CallLogWrapper& gl, const TextureGenerationSpec& spec) = 0;
    832 	virtual void						generateTestIterations	(std::vector<TextureGenerationSpec>& iterations) = 0;
    833 
    834 	const QueryType						m_type;
    835 	const glw::GLenum					m_target;
    836 	glw::GLuint							m_texture;
    837 	glw::GLuint							m_texBuffer;
    838 
    839 private:
    840 	int									m_iteration;
    841 	std::vector<TextureGenerationSpec>	m_iterations;
    842 	bool								m_allIterationsOk;
    843 	std::vector<int>					m_failedIterations;
    844 };
    845 
    846 TextureLevelCase::TextureLevelCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
    847 	: TestCase			(ctx, name, desc)
    848 	, m_type			(type)
    849 	, m_target			(target)
    850 	, m_texture			(0)
    851 	, m_texBuffer		(0)
    852 	, m_iteration		(0)
    853 	, m_allIterationsOk	(true)
    854 {
    855 }
    856 
    857 TextureLevelCase::~TextureLevelCase (void)
    858 {
    859 	deinit();
    860 }
    861 
    862 void TextureLevelCase::init (void)
    863 {
    864 	if (!isCoreTextureTarget(m_target, m_context.getRenderContext().getType()))
    865 	{
    866 		const char* const targetExtension = getTextureTargetExtension(m_target);
    867 
    868 		if (!m_context.getContextInfo().isExtensionSupported(targetExtension))
    869 			throw tcu::NotSupportedError("Test requires " + std::string(targetExtension) + " extension");
    870 	}
    871 
    872 	generateTestIterations(m_iterations);
    873 
    874 	for (int iterationNdx = 0; iterationNdx < (int)m_iterations.size(); ++iterationNdx)
    875 		DE_ASSERT(m_iterations[iterationNdx].bindTarget == m_target);
    876 }
    877 
    878 void TextureLevelCase::deinit (void)
    879 {
    880 	if (m_texture)
    881 	{
    882 		m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texture);
    883 		m_texture = 0;
    884 	}
    885 	if (m_texBuffer)
    886 	{
    887 		m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texBuffer);
    888 		m_texBuffer = 0;
    889 	}
    890 }
    891 
    892 void TextureLevelCase::getFormatSamples (glw::GLenum internalFormat, std::vector<int>& samples)
    893 {
    894 	const glw::Functions	gl			= m_context.getRenderContext().getFunctions();
    895 	int						sampleCount	= -1;
    896 
    897 	if (!isMultisampleTarget(m_target))
    898 		return;
    899 
    900 	gl.getInternalformativ(m_target, internalFormat, GL_NUM_SAMPLE_COUNTS, 1, &sampleCount);
    901 
    902 	if (sampleCount < 0)
    903 		throw tcu::TestError("internal format query failed");
    904 
    905 	samples.resize(sampleCount);
    906 
    907 	if (sampleCount > 0)
    908 	{
    909 		gl.getInternalformativ(m_target, internalFormat, GL_SAMPLES, sampleCount, &samples[0]);
    910 		GLU_EXPECT_NO_ERROR(gl.getError(), "get max samples");
    911 	}
    912 }
    913 
    914 TextureLevelCase::IterateResult TextureLevelCase::iterate (void)
    915 {
    916 	const bool result = testConfig(m_iterations[m_iteration]);
    917 
    918 	if (!result)
    919 	{
    920 		m_failedIterations.push_back(m_iteration);
    921 		m_allIterationsOk = false;
    922 	}
    923 
    924 	if (++m_iteration < (int)m_iterations.size())
    925 		return CONTINUE;
    926 
    927 	if (m_allIterationsOk)
    928 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    929 	else
    930 	{
    931 		tcu::MessageBuilder msg(&m_testCtx.getLog());
    932 
    933 		msg << "Following iteration(s) failed: ";
    934 		for (int ndx = 0; ndx < (int)m_failedIterations.size(); ++ndx)
    935 		{
    936 			if (ndx)
    937 				msg << ", ";
    938 			msg << (m_failedIterations[ndx] + 1);
    939 		}
    940 		msg << tcu::TestLog::EndMessage;
    941 
    942 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more iterations failed");
    943 	}
    944 	return STOP;
    945 }
    946 
    947 bool TextureLevelCase::testConfig (const TextureGenerationSpec& spec)
    948 {
    949 	const tcu::ScopedLogSection section(m_testCtx.getLog(), "Iteration", std::string() + "Iteration " + de::toString(m_iteration+1) + "/" + de::toString((int)m_iterations.size()) + " - " + spec.description);
    950 	glu::CallLogWrapper			gl		(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
    951 	bool						result;
    952 
    953 	gl.enableLogging(true);
    954 
    955 	gl.glGenTextures(1, &m_texture);
    956 	gl.glBindTexture(spec.bindTarget, m_texture);
    957 	GLU_EXPECT_NO_ERROR(gl.glGetError(), "gen tex");
    958 
    959 	// Set the state
    960 	applyTextureGenerationSpec(gl, spec, m_texBuffer);
    961 
    962 	// Verify the state
    963 	result = checkTextureState(gl, spec);
    964 
    965 	gl.glDeleteTextures(1, &m_texture);
    966 	m_texture = 0;
    967 
    968 	if (m_texBuffer)
    969 	{
    970 		gl.glDeleteBuffers(1, &m_texBuffer);
    971 		m_texture = 0;
    972 	}
    973 
    974 	return result;
    975 }
    976 
    977 /*--------------------------------------------------------------------*//*!
    978  * \brief Test texture target
    979  *//*--------------------------------------------------------------------*/
    980 class TextureLevelCommonCase : public TextureLevelCase
    981 {
    982 public:
    983 						TextureLevelCommonCase	(Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type);
    984 
    985 protected:
    986 	virtual void		generateTestIterations	(std::vector<TextureGenerationSpec>& iterations);
    987 };
    988 
    989 TextureLevelCommonCase::TextureLevelCommonCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
    990 	: TextureLevelCase(ctx, name, desc, target, type)
    991 {
    992 }
    993 
    994 void TextureLevelCommonCase::generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
    995 {
    996 	const glw::GLenum	internalFormat = GL_RGBA8;
    997 	int					maxSamples;
    998 	std::vector<int>	samples;
    999 
   1000 	getFormatSamples(internalFormat, samples);
   1001 	if (samples.empty())
   1002 		maxSamples = -1;
   1003 	else
   1004 		maxSamples = samples[0];
   1005 
   1006 	generateColorTextureGenerationGroup(iterations, m_target, maxSamples, internalFormat);
   1007 }
   1008 
   1009 class TextureLevelSampleCase : public TextureLevelCommonCase
   1010 {
   1011 public:
   1012 	TextureLevelSampleCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
   1013 		: TextureLevelCommonCase(ctx, name, desc, target, type)
   1014 	{
   1015 	}
   1016 
   1017 private:
   1018 	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
   1019 	{
   1020 		const int queryLevel	= (spec.levels.empty()) ? (0) : (spec.levels[0].level);
   1021 		const int refValue		= (spec.levels.empty()) ? (0) : (spec.sampleCount);
   1022 
   1023 		return verifyTextureLevelParameterGreaterOrEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_SAMPLES, refValue, m_type);
   1024 	}
   1025 };
   1026 
   1027 class TextureLevelFixedSamplesCase : public TextureLevelCommonCase
   1028 {
   1029 public:
   1030 	TextureLevelFixedSamplesCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
   1031 		: TextureLevelCommonCase(ctx, name, desc, target, type)
   1032 	{
   1033 	}
   1034 
   1035 private:
   1036 	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
   1037 	{
   1038 		const int queryLevel	= (spec.levels.empty()) ? (0) : (spec.levels[0].level);
   1039 		const int refValue		= (spec.levels.empty()) ? (1) : ((spec.fixedSamplePos) ? (1) : (0));
   1040 
   1041 		return verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_FIXED_SAMPLE_LOCATIONS, refValue, m_type);
   1042 	}
   1043 };
   1044 
   1045 class TextureLevelWidthCase : public TextureLevelCommonCase
   1046 {
   1047 public:
   1048 	TextureLevelWidthCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
   1049 		: TextureLevelCommonCase(ctx, name, desc, target, type)
   1050 	{
   1051 	}
   1052 
   1053 private:
   1054 	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
   1055 	{
   1056 		const int	initialValue	= 0;
   1057 		bool		allOk			= true;
   1058 
   1059 		if (spec.levels.empty())
   1060 		{
   1061 			const int queryLevel	= 0;
   1062 			const int refValue		= initialValue;
   1063 
   1064 			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_WIDTH, refValue, m_type);
   1065 		}
   1066 		else
   1067 		{
   1068 			for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx)
   1069 			{
   1070 				const int queryLevel	= spec.levels[levelNdx].level;
   1071 				const int refValue		= spec.levels[levelNdx].width;
   1072 
   1073 				allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_WIDTH, refValue, m_type);
   1074 			}
   1075 		}
   1076 
   1077 		return allOk;
   1078 	}
   1079 };
   1080 
   1081 class TextureLevelHeightCase : public TextureLevelCommonCase
   1082 {
   1083 public:
   1084 	TextureLevelHeightCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
   1085 		: TextureLevelCommonCase(ctx, name, desc, target, type)
   1086 	{
   1087 	}
   1088 
   1089 private:
   1090 	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
   1091 	{
   1092 		const int	initialValue	= 0;
   1093 		bool		allOk			= true;
   1094 
   1095 		if (spec.levels.empty())
   1096 		{
   1097 			const int queryLevel	= 0;
   1098 			const int refValue		= initialValue;
   1099 
   1100 			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_HEIGHT, refValue, m_type);
   1101 		}
   1102 		else
   1103 		{
   1104 			for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx)
   1105 			{
   1106 				const int queryLevel	= spec.levels[levelNdx].level;
   1107 				const int refValue		= spec.levels[levelNdx].height;
   1108 
   1109 				allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_HEIGHT, refValue, m_type);
   1110 			}
   1111 		}
   1112 
   1113 		return allOk;
   1114 	}
   1115 };
   1116 
   1117 class TextureLevelDepthCase : public TextureLevelCommonCase
   1118 {
   1119 public:
   1120 	TextureLevelDepthCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
   1121 		: TextureLevelCommonCase(ctx, name, desc, target, type)
   1122 	{
   1123 	}
   1124 
   1125 private:
   1126 
   1127 	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
   1128 	{
   1129 		const int	initialValue	= 0;
   1130 		bool		allOk			= true;
   1131 
   1132 		if (spec.levels.empty())
   1133 		{
   1134 			const int queryLevel	= 0;
   1135 			const int refValue		= initialValue;
   1136 
   1137 			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_DEPTH, refValue, m_type);
   1138 		}
   1139 		else
   1140 		{
   1141 			for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx)
   1142 			{
   1143 				const int queryLevel	= spec.levels[levelNdx].level;
   1144 				const int refValue		= spec.levels[levelNdx].depth;
   1145 
   1146 				allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_DEPTH, refValue, m_type);
   1147 			}
   1148 		}
   1149 
   1150 		return allOk;
   1151 	}
   1152 };
   1153 
   1154 class TextureLevelInternalFormatCase : public TextureLevelCase
   1155 {
   1156 public:
   1157 	TextureLevelInternalFormatCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
   1158 		: TextureLevelCase(ctx, name, desc, target, type)
   1159 	{
   1160 	}
   1161 
   1162 private:
   1163 	void generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
   1164 	{
   1165 		generateInternalFormatTextureGenerationGroup(iterations, m_target);
   1166 	}
   1167 
   1168 	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
   1169 	{
   1170 		bool allOk = true;
   1171 
   1172 		if (spec.levels.empty())
   1173 		{
   1174 			const int queryLevel		= 0;
   1175 			const int initialValues[2]	= { GL_RGBA, GL_R8 };
   1176 
   1177 			allOk &= verifyTextureLevelParameterInternalFormatAnyOf(gl, spec.queryTarget, queryLevel, GL_TEXTURE_INTERNAL_FORMAT, initialValues, DE_LENGTH_OF_ARRAY(initialValues), m_type);
   1178 		}
   1179 		else
   1180 		{
   1181 			for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx)
   1182 			{
   1183 				const int queryLevel	= spec.levels[levelNdx].level;
   1184 				const int refValue		= spec.levels[levelNdx].internalFormat;
   1185 
   1186 				allOk &= verifyTextureLevelParameterInternalFormatEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_INTERNAL_FORMAT, refValue, m_type);
   1187 			}
   1188 		}
   1189 
   1190 		return allOk;
   1191 	}
   1192 };
   1193 
   1194 class TextureLevelSizeCase : public TextureLevelCase
   1195 {
   1196 public:
   1197 						TextureLevelSizeCase			(Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type, glw::GLenum pname);
   1198 
   1199 private:
   1200 	void				generateTestIterations			(std::vector<TextureGenerationSpec>& iterations);
   1201 	bool				checkTextureState				(glu::CallLogWrapper& gl, const TextureGenerationSpec& spec);
   1202 	int					getMinimumComponentResolution	(glw::GLenum internalFormat);
   1203 
   1204 	const glw::GLenum	m_pname;
   1205 };
   1206 
   1207 TextureLevelSizeCase::TextureLevelSizeCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type, glw::GLenum pname)
   1208 	: TextureLevelCase	(ctx, name, desc, target, type)
   1209 	, m_pname			(pname)
   1210 {
   1211 }
   1212 
   1213 void TextureLevelSizeCase::generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
   1214 {
   1215 	generateInternalFormatTextureGenerationGroup(iterations, m_target);
   1216 }
   1217 
   1218 bool TextureLevelSizeCase::checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
   1219 {
   1220 	bool allOk = true;
   1221 
   1222 	if (spec.levels.empty())
   1223 	{
   1224 		allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, m_pname, 0, m_type);
   1225 	}
   1226 	else
   1227 	{
   1228 		for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx)
   1229 		{
   1230 			const int queryLevel	= spec.levels[levelNdx].level;
   1231 			const int refValue		= getMinimumComponentResolution(spec.levels[levelNdx].internalFormat);
   1232 
   1233 			allOk &= verifyTextureLevelParameterGreaterOrEqual(gl, spec.queryTarget, queryLevel, m_pname, refValue, m_type);
   1234 		}
   1235 	}
   1236 
   1237 	return allOk;
   1238 }
   1239 
   1240 int TextureLevelSizeCase::getMinimumComponentResolution (glw::GLenum internalFormat)
   1241 {
   1242 	const tcu::TextureFormat	format			= glu::mapGLInternalFormat(internalFormat);
   1243 	const tcu::IVec4			channelBitDepth	= tcu::getTextureFormatBitDepth(format);
   1244 
   1245 	switch (m_pname)
   1246 	{
   1247 		case GL_TEXTURE_RED_SIZE:
   1248 			if (format.order == tcu::TextureFormat::R		||
   1249 				format.order == tcu::TextureFormat::RG		||
   1250 				format.order == tcu::TextureFormat::RGB		||
   1251 				format.order == tcu::TextureFormat::RGBA	||
   1252 				format.order == tcu::TextureFormat::BGRA	||
   1253 				format.order == tcu::TextureFormat::ARGB	||
   1254 				format.order == tcu::TextureFormat::sRGB	||
   1255 				format.order == tcu::TextureFormat::sRGBA)
   1256 				return channelBitDepth[0];
   1257 			else
   1258 				return 0;
   1259 
   1260 		case GL_TEXTURE_GREEN_SIZE:
   1261 			if (format.order == tcu::TextureFormat::RG		||
   1262 				format.order == tcu::TextureFormat::RGB		||
   1263 				format.order == tcu::TextureFormat::RGBA	||
   1264 				format.order == tcu::TextureFormat::BGRA	||
   1265 				format.order == tcu::TextureFormat::ARGB	||
   1266 				format.order == tcu::TextureFormat::sRGB	||
   1267 				format.order == tcu::TextureFormat::sRGBA)
   1268 				return channelBitDepth[1];
   1269 			else
   1270 				return 0;
   1271 
   1272 		case GL_TEXTURE_BLUE_SIZE:
   1273 			if (format.order == tcu::TextureFormat::RGB		||
   1274 				format.order == tcu::TextureFormat::RGBA	||
   1275 				format.order == tcu::TextureFormat::BGRA	||
   1276 				format.order == tcu::TextureFormat::ARGB	||
   1277 				format.order == tcu::TextureFormat::sRGB	||
   1278 				format.order == tcu::TextureFormat::sRGBA)
   1279 				return channelBitDepth[2];
   1280 			else
   1281 				return 0;
   1282 
   1283 		case GL_TEXTURE_ALPHA_SIZE:
   1284 			if (format.order == tcu::TextureFormat::RGBA	||
   1285 				format.order == tcu::TextureFormat::BGRA	||
   1286 				format.order == tcu::TextureFormat::ARGB	||
   1287 				format.order == tcu::TextureFormat::sRGBA)
   1288 				return channelBitDepth[3];
   1289 			else
   1290 				return 0;
   1291 
   1292 		case GL_TEXTURE_DEPTH_SIZE:
   1293 			if (format.order == tcu::TextureFormat::D	||
   1294 				format.order == tcu::TextureFormat::DS)
   1295 				return channelBitDepth[0];
   1296 			else
   1297 				return 0;
   1298 
   1299 		case GL_TEXTURE_STENCIL_SIZE:
   1300 			if (format.order == tcu::TextureFormat::DS)
   1301 				return channelBitDepth[3];
   1302 			else
   1303 				return 0;
   1304 
   1305 		case GL_TEXTURE_SHARED_SIZE:
   1306 			if (internalFormat == GL_RGB9_E5)
   1307 				return 5;
   1308 			else
   1309 				return 0;
   1310 		default:
   1311 			DE_ASSERT(DE_FALSE);
   1312 			return 0;
   1313 	}
   1314 }
   1315 
   1316 class TextureLevelTypeCase : public TextureLevelCase
   1317 {
   1318 public:
   1319 						TextureLevelTypeCase			(Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type, glw::GLenum pname);
   1320 
   1321 private:
   1322 	void				generateTestIterations			(std::vector<TextureGenerationSpec>& iterations);
   1323 	bool				checkTextureState				(glu::CallLogWrapper& gl, const TextureGenerationSpec& spec);
   1324 	int					getComponentType				(glw::GLenum internalFormat);
   1325 
   1326 	const glw::GLenum	m_pname;
   1327 };
   1328 
   1329 TextureLevelTypeCase::TextureLevelTypeCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type, glw::GLenum pname)
   1330 	: TextureLevelCase	(ctx, name, desc, target, type)
   1331 	, m_pname			(pname)
   1332 {
   1333 }
   1334 
   1335 void TextureLevelTypeCase::generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
   1336 {
   1337 	generateInternalFormatTextureGenerationGroup(iterations, m_target);
   1338 }
   1339 
   1340 bool TextureLevelTypeCase::checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
   1341 {
   1342 	bool allOk = true;
   1343 
   1344 	if (spec.levels.empty())
   1345 	{
   1346 		allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, m_pname, GL_NONE, m_type);
   1347 	}
   1348 	else
   1349 	{
   1350 		for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx)
   1351 		{
   1352 			const int queryLevel	= spec.levels[levelNdx].level;
   1353 			const int refValue		= getComponentType(spec.levels[levelNdx].internalFormat);
   1354 
   1355 			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, m_pname, refValue, m_type);
   1356 		}
   1357 	}
   1358 
   1359 	return allOk;
   1360 }
   1361 
   1362 int TextureLevelTypeCase::getComponentType (glw::GLenum internalFormat)
   1363 {
   1364 	const tcu::TextureFormat		format			= glu::mapGLInternalFormat(internalFormat);
   1365 	const tcu::TextureChannelClass	channelClass	= tcu::getTextureChannelClass(format.type);
   1366 	glw::GLenum						channelType		= GL_NONE;
   1367 
   1368 	// depth-stencil special cases
   1369 	if (format.type == tcu::TextureFormat::UNSIGNED_INT_24_8)
   1370 	{
   1371 		if (m_pname == GL_TEXTURE_DEPTH_TYPE)
   1372 			return GL_UNSIGNED_NORMALIZED;
   1373 		else
   1374 			return GL_NONE;
   1375 	}
   1376 	else if (format.type == tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV)
   1377 	{
   1378 		if (m_pname == GL_TEXTURE_DEPTH_TYPE)
   1379 			return GL_FLOAT;
   1380 		else
   1381 			return GL_NONE;
   1382 	}
   1383 	else
   1384 	{
   1385 		switch (channelClass)
   1386 		{
   1387 			case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:		channelType = GL_SIGNED_NORMALIZED;		break;
   1388 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:		channelType = GL_UNSIGNED_NORMALIZED;	break;
   1389 			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:			channelType = GL_INT;					break;
   1390 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:			channelType = GL_UNSIGNED_INT;			break;
   1391 			case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:			channelType = GL_FLOAT;					break;
   1392 			default:
   1393 				DE_ASSERT(DE_FALSE);
   1394 		}
   1395 	}
   1396 
   1397 	switch (m_pname)
   1398 	{
   1399 		case GL_TEXTURE_RED_TYPE:
   1400 			if (format.order == tcu::TextureFormat::R		||
   1401 				format.order == tcu::TextureFormat::RG		||
   1402 				format.order == tcu::TextureFormat::RGB		||
   1403 				format.order == tcu::TextureFormat::RGBA	||
   1404 				format.order == tcu::TextureFormat::BGRA	||
   1405 				format.order == tcu::TextureFormat::ARGB	||
   1406 				format.order == tcu::TextureFormat::sRGB	||
   1407 				format.order == tcu::TextureFormat::sRGBA)
   1408 				return channelType;
   1409 			else
   1410 				return GL_NONE;
   1411 
   1412 		case GL_TEXTURE_GREEN_TYPE:
   1413 			if (format.order == tcu::TextureFormat::RG		||
   1414 				format.order == tcu::TextureFormat::RGB		||
   1415 				format.order == tcu::TextureFormat::RGBA	||
   1416 				format.order == tcu::TextureFormat::BGRA	||
   1417 				format.order == tcu::TextureFormat::ARGB	||
   1418 				format.order == tcu::TextureFormat::sRGB	||
   1419 				format.order == tcu::TextureFormat::sRGBA)
   1420 				return channelType;
   1421 			else
   1422 				return GL_NONE;
   1423 
   1424 		case GL_TEXTURE_BLUE_TYPE:
   1425 			if (format.order == tcu::TextureFormat::RGB		||
   1426 				format.order == tcu::TextureFormat::RGBA	||
   1427 				format.order == tcu::TextureFormat::BGRA	||
   1428 				format.order == tcu::TextureFormat::ARGB	||
   1429 				format.order == tcu::TextureFormat::sRGB	||
   1430 				format.order == tcu::TextureFormat::sRGBA)
   1431 				return channelType;
   1432 			else
   1433 				return GL_NONE;
   1434 
   1435 		case GL_TEXTURE_ALPHA_TYPE:
   1436 			if (format.order == tcu::TextureFormat::RGBA	||
   1437 				format.order == tcu::TextureFormat::BGRA	||
   1438 				format.order == tcu::TextureFormat::ARGB	||
   1439 				format.order == tcu::TextureFormat::sRGBA)
   1440 				return channelType;
   1441 			else
   1442 				return GL_NONE;
   1443 
   1444 		case GL_TEXTURE_DEPTH_TYPE:
   1445 			if (format.order == tcu::TextureFormat::D	||
   1446 				format.order == tcu::TextureFormat::DS)
   1447 				return channelType;
   1448 			else
   1449 				return GL_NONE;
   1450 
   1451 		default:
   1452 			DE_ASSERT(DE_FALSE);
   1453 			return 0;
   1454 	}
   1455 }
   1456 
   1457 class TextureLevelCompressedCase : public TextureLevelCase
   1458 {
   1459 public:
   1460 	TextureLevelCompressedCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
   1461 		: TextureLevelCase(ctx, name, desc, target, type)
   1462 	{
   1463 	}
   1464 
   1465 private:
   1466 	void generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
   1467 	{
   1468 		generateCompressedTextureGenerationGroup(iterations, m_target);
   1469 	}
   1470 
   1471 	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
   1472 	{
   1473 		bool allOk = true;
   1474 
   1475 		if (spec.levels.empty())
   1476 		{
   1477 			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, GL_TEXTURE_COMPRESSED, 0, m_type);
   1478 		}
   1479 		else
   1480 		{
   1481 			for (int levelNdx = 0; levelNdx < (int)spec.levels.size(); ++levelNdx)
   1482 			{
   1483 				const int queryLevel	= spec.levels[levelNdx].level;
   1484 				const int refValue		= (spec.levels[levelNdx].compressed) ? (1) : (0);
   1485 
   1486 				allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, queryLevel, GL_TEXTURE_COMPRESSED, refValue, m_type);
   1487 			}
   1488 		}
   1489 
   1490 		return allOk;
   1491 	}
   1492 };
   1493 
   1494 class TextureLevelBufferDataStoreCase : public TextureLevelCase
   1495 {
   1496 public:
   1497 	TextureLevelBufferDataStoreCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
   1498 		: TextureLevelCase(ctx, name, desc, target, type)
   1499 	{
   1500 	}
   1501 
   1502 private:
   1503 	void init (void)
   1504 	{
   1505 		if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_buffer") &&
   1506 			!glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)))
   1507 			throw tcu::NotSupportedError("Test requires GL_EXT_texture_buffer extension");
   1508 		TextureLevelCase::init();
   1509 	}
   1510 
   1511 	void generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
   1512 	{
   1513 		generateTextureBufferGenerationGroup(iterations, m_target);
   1514 	}
   1515 
   1516 	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
   1517 	{
   1518 		bool allOk = true;
   1519 
   1520 		if (spec.levels.empty())
   1521 		{
   1522 			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, GL_TEXTURE_BUFFER_DATA_STORE_BINDING, 0, m_type);
   1523 		}
   1524 		else
   1525 		{
   1526 			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, GL_TEXTURE_BUFFER_DATA_STORE_BINDING, m_texBuffer, m_type);
   1527 		}
   1528 
   1529 		return allOk;
   1530 	}
   1531 };
   1532 
   1533 class TextureLevelBufferDataOffsetCase : public TextureLevelCase
   1534 {
   1535 public:
   1536 	TextureLevelBufferDataOffsetCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
   1537 		: TextureLevelCase(ctx, name, desc, target, type)
   1538 	{
   1539 	}
   1540 
   1541 private:
   1542 	void init (void)
   1543 	{
   1544 		if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_buffer") &&
   1545 			!glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)))
   1546 			throw tcu::NotSupportedError("Test requires GL_EXT_texture_buffer extension");
   1547 		TextureLevelCase::init();
   1548 	}
   1549 
   1550 	void generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
   1551 	{
   1552 		generateTextureBufferGenerationGroup(iterations, m_target);
   1553 	}
   1554 
   1555 	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
   1556 	{
   1557 		bool allOk = true;
   1558 
   1559 		if (spec.levels.empty())
   1560 		{
   1561 			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, GL_TEXTURE_BUFFER_OFFSET, 0, m_type);
   1562 		}
   1563 		else
   1564 		{
   1565 			const int refValue = spec.texBufferDataOffset;
   1566 
   1567 			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, GL_TEXTURE_BUFFER_OFFSET, refValue, m_type);
   1568 		}
   1569 
   1570 		return allOk;
   1571 	}
   1572 };
   1573 
   1574 class TextureLevelBufferDataSizeCase : public TextureLevelCase
   1575 {
   1576 public:
   1577 	TextureLevelBufferDataSizeCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
   1578 		: TextureLevelCase(ctx, name, desc, target, type)
   1579 	{
   1580 	}
   1581 
   1582 private:
   1583 	void init (void)
   1584 	{
   1585 		if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_buffer") &&
   1586 			!glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)))
   1587 			throw tcu::NotSupportedError("Test requires GL_EXT_texture_buffer extension");
   1588 		TextureLevelCase::init();
   1589 	}
   1590 
   1591 	void generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
   1592 	{
   1593 		generateTextureBufferGenerationGroup(iterations, m_target);
   1594 	}
   1595 
   1596 	bool checkTextureState (glu::CallLogWrapper& gl, const TextureGenerationSpec& spec)
   1597 	{
   1598 		bool allOk = true;
   1599 
   1600 		if (spec.levels.empty())
   1601 		{
   1602 			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, GL_TEXTURE_BUFFER_SIZE, 0, m_type);
   1603 		}
   1604 		else
   1605 		{
   1606 			const int refValue = spec.texBufferDataSize;
   1607 
   1608 			allOk &= verifyTextureLevelParameterEqual(gl, spec.queryTarget, 0, GL_TEXTURE_BUFFER_SIZE, refValue, m_type);
   1609 		}
   1610 
   1611 		return allOk;
   1612 	}
   1613 };
   1614 
   1615 } // anonymous
   1616 
   1617 static const char* getVerifierSuffix (QueryType type)
   1618 {
   1619 	switch (type)
   1620 	{
   1621 		case QUERY_TEXTURE_LEVEL_FLOAT:		return "_float";
   1622 		case QUERY_TEXTURE_LEVEL_INTEGER:	return "_integer";
   1623 		default:
   1624 			DE_ASSERT(DE_FALSE);
   1625 			return DE_NULL;
   1626 	}
   1627 }
   1628 
   1629 TextureLevelStateQueryTests::TextureLevelStateQueryTests (Context& context)
   1630 	: TestCaseGroup(context, "texture_level", "GetTexLevelParameter tests")
   1631 {
   1632 }
   1633 
   1634 TextureLevelStateQueryTests::~TextureLevelStateQueryTests (void)
   1635 {
   1636 }
   1637 
   1638 void TextureLevelStateQueryTests::init (void)
   1639 {
   1640 	static const QueryType verifiers[] =
   1641 	{
   1642 		QUERY_TEXTURE_LEVEL_INTEGER,
   1643 		QUERY_TEXTURE_LEVEL_FLOAT,
   1644 	};
   1645 
   1646 #define FOR_EACH_VERIFIER(X) \
   1647 	for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(verifiers); ++verifierNdx)	\
   1648 	{																						\
   1649 		const std::string verifierSuffix = getVerifierSuffix(verifiers[verifierNdx]);		\
   1650 		const QueryType verifier = verifiers[verifierNdx];									\
   1651 		targetGroup->addChild(X);															\
   1652 	}
   1653 	static const struct
   1654 	{
   1655 		const char*	name;
   1656 		glw::GLenum	target;
   1657 	} textureTargets[] =
   1658 	{
   1659 		{ "texture_2d",						GL_TEXTURE_2D,						},
   1660 		{ "texture_3d",						GL_TEXTURE_3D,						},
   1661 		{ "texture_2d_array",				GL_TEXTURE_2D_ARRAY,				},
   1662 		{ "texture_cube_map",				GL_TEXTURE_CUBE_MAP,				},
   1663 		{ "texture_2d_multisample",			GL_TEXTURE_2D_MULTISAMPLE,			},
   1664 		{ "texture_2d_multisample_array",	GL_TEXTURE_2D_MULTISAMPLE_ARRAY,	}, // GL_OES_texture_storage_multisample_2d_array
   1665 		{ "texture_buffer",					GL_TEXTURE_BUFFER,					}, // GL_EXT_texture_buffer
   1666 		{ "texture_cube_array",				GL_TEXTURE_CUBE_MAP_ARRAY,			}, // GL_EXT_texture_cube_map_array
   1667 	};
   1668 
   1669 	for (int targetNdx = 0; targetNdx < DE_LENGTH_OF_ARRAY(textureTargets); ++targetNdx)
   1670 	{
   1671 		tcu::TestCaseGroup* const targetGroup = new tcu::TestCaseGroup(m_testCtx, textureTargets[targetNdx].name, textureTargets[targetNdx].name);
   1672 		addChild(targetGroup);
   1673 
   1674 		FOR_EACH_VERIFIER(new TextureLevelSampleCase			(m_context, ("samples" + verifierSuffix).c_str(),					"Verify TEXTURE_SAMPLES",					textureTargets[targetNdx].target,	verifier));
   1675 		FOR_EACH_VERIFIER(new TextureLevelFixedSamplesCase		(m_context, ("fixed_sample_locations" + verifierSuffix).c_str(),	"Verify TEXTURE_FIXED_SAMPLE_LOCATIONS",	textureTargets[targetNdx].target,	verifier));
   1676 		FOR_EACH_VERIFIER(new TextureLevelWidthCase				(m_context, ("width" + verifierSuffix).c_str(),						"Verify TEXTURE_WIDTH",						textureTargets[targetNdx].target,	verifier));
   1677 		FOR_EACH_VERIFIER(new TextureLevelHeightCase			(m_context, ("height" + verifierSuffix).c_str(),					"Verify TEXTURE_HEIGHT",					textureTargets[targetNdx].target,	verifier));
   1678 		FOR_EACH_VERIFIER(new TextureLevelDepthCase				(m_context, ("depth" + verifierSuffix).c_str(),						"Verify TEXTURE_DEPTH",						textureTargets[targetNdx].target,	verifier));
   1679 		FOR_EACH_VERIFIER(new TextureLevelInternalFormatCase	(m_context, ("internal_format" + verifierSuffix).c_str(),			"Verify TEXTURE_INTERNAL_FORMAT",			textureTargets[targetNdx].target,	verifier));
   1680 		FOR_EACH_VERIFIER(new TextureLevelSizeCase				(m_context, ("red_size" + verifierSuffix).c_str(),					"Verify TEXTURE_RED_SIZE",					textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_RED_SIZE));
   1681 		FOR_EACH_VERIFIER(new TextureLevelSizeCase				(m_context, ("green_size" + verifierSuffix).c_str(),				"Verify TEXTURE_GREEN_SIZE",				textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_GREEN_SIZE));
   1682 		FOR_EACH_VERIFIER(new TextureLevelSizeCase				(m_context, ("blue_size" + verifierSuffix).c_str(),					"Verify TEXTURE_BLUE_SIZE",					textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_BLUE_SIZE));
   1683 		FOR_EACH_VERIFIER(new TextureLevelSizeCase				(m_context, ("alpha_size" + verifierSuffix).c_str(),				"Verify TEXTURE_ALPHA_SIZE",				textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_ALPHA_SIZE));
   1684 		FOR_EACH_VERIFIER(new TextureLevelSizeCase				(m_context, ("depth_size" + verifierSuffix).c_str(),				"Verify TEXTURE_DEPTH_SIZE",				textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_DEPTH_SIZE));
   1685 		FOR_EACH_VERIFIER(new TextureLevelSizeCase				(m_context, ("stencil_size" + verifierSuffix).c_str(),				"Verify TEXTURE_STENCIL_SIZE",				textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_STENCIL_SIZE));
   1686 		FOR_EACH_VERIFIER(new TextureLevelSizeCase				(m_context, ("shared_size" + verifierSuffix).c_str(),				"Verify TEXTURE_SHARED_SIZE",				textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_SHARED_SIZE));
   1687 		FOR_EACH_VERIFIER(new TextureLevelTypeCase				(m_context, ("red_type" + verifierSuffix).c_str(),					"Verify TEXTURE_RED_TYPE",					textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_RED_TYPE));
   1688 		FOR_EACH_VERIFIER(new TextureLevelTypeCase				(m_context, ("green_type" + verifierSuffix).c_str(),				"Verify TEXTURE_GREEN_TYPE",				textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_GREEN_TYPE));
   1689 		FOR_EACH_VERIFIER(new TextureLevelTypeCase				(m_context, ("blue_type" + verifierSuffix).c_str(),					"Verify TEXTURE_BLUE_TYPE",					textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_BLUE_TYPE));
   1690 		FOR_EACH_VERIFIER(new TextureLevelTypeCase				(m_context, ("alpha_type" + verifierSuffix).c_str(),				"Verify TEXTURE_ALPHA_TYPE",				textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_ALPHA_TYPE));
   1691 		FOR_EACH_VERIFIER(new TextureLevelTypeCase				(m_context, ("depth_type" + verifierSuffix).c_str(),				"Verify TEXTURE_DEPTH_TYPE",				textureTargets[targetNdx].target,	verifier,	GL_TEXTURE_DEPTH_TYPE));
   1692 		FOR_EACH_VERIFIER(new TextureLevelCompressedCase		(m_context, ("compressed" + verifierSuffix).c_str(),				"Verify TEXTURE_COMPRESSED",				textureTargets[targetNdx].target,	verifier));
   1693 		FOR_EACH_VERIFIER(new TextureLevelBufferDataStoreCase	(m_context, ("buffer_data_store_binding" + verifierSuffix).c_str(),	"Verify TEXTURE_BUFFER_DATA_STORE_BINDING",	textureTargets[targetNdx].target,	verifier));
   1694 		FOR_EACH_VERIFIER(new TextureLevelBufferDataOffsetCase	(m_context, ("buffer_offset" + verifierSuffix).c_str(),				"Verify TEXTURE_BUFFER_OFFSET",				textureTargets[targetNdx].target,	verifier));
   1695 		FOR_EACH_VERIFIER(new TextureLevelBufferDataSizeCase	(m_context, ("buffer_size" + verifierSuffix).c_str(),				"Verify TEXTURE_BUFFER_SIZE",				textureTargets[targetNdx].target,	verifier));
   1696 	}
   1697 
   1698 #undef FOR_EACH_VERIFIER
   1699 }
   1700 
   1701 } // Functional
   1702 } // gles31
   1703 } // deqp
   1704