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
39namespace deqp
40{
41namespace gles31
42{
43namespace Functional
44{
45namespace
46{
47
48using namespace gls::StateQueryUtil;
49
50
51static 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
69static 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
87static 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
100static 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
121struct 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};
164struct 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
170struct 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
176template <typename Printer>
177static 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
193static 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
198static 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
203static 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
219static 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
270static bool isDepthFormat (const tcu::TextureFormat& fmt)
271{
272	return fmt.order == tcu::TextureFormat::D || fmt.order == tcu::TextureFormat::DS;
273}
274
275static 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
307static 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
317static 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
351static 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
364static bool isCompressionSupportedForTarget (glw::GLenum target)
365{
366	return target == GL_TEXTURE_2D || target == GL_TEXTURE_2D_ARRAY;
367}
368
369static bool isMultisampleTarget (glw::GLenum target)
370{
371	return target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
372}
373
374static 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
381static int getPixelSize (glw::GLenum internalFormat)
382{
383	const tcu::TextureFormat fmt = glu::mapGLInternalFormat(internalFormat);
384	return fmt.getPixelSize();
385}
386
387static 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
586static 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
674static 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
712static 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
731bool 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
818class TextureLevelCase : public TestCase
819{
820public:
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
828protected:
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
839private:
840	int									m_iteration;
841	std::vector<TextureGenerationSpec>	m_iterations;
842	bool								m_allIterationsOk;
843	std::vector<int>					m_failedIterations;
844};
845
846TextureLevelCase::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
857TextureLevelCase::~TextureLevelCase (void)
858{
859	deinit();
860}
861
862void 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
878void 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
892void 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
914TextureLevelCase::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
947bool 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 *//*--------------------------------------------------------------------*/
980class TextureLevelCommonCase : public TextureLevelCase
981{
982public:
983						TextureLevelCommonCase	(Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type);
984
985protected:
986	virtual void		generateTestIterations	(std::vector<TextureGenerationSpec>& iterations);
987};
988
989TextureLevelCommonCase::TextureLevelCommonCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
990	: TextureLevelCase(ctx, name, desc, target, type)
991{
992}
993
994void 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
1009class TextureLevelSampleCase : public TextureLevelCommonCase
1010{
1011public:
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
1017private:
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
1027class TextureLevelFixedSamplesCase : public TextureLevelCommonCase
1028{
1029public:
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
1035private:
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
1045class TextureLevelWidthCase : public TextureLevelCommonCase
1046{
1047public:
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
1053private:
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
1081class TextureLevelHeightCase : public TextureLevelCommonCase
1082{
1083public:
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
1089private:
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
1117class TextureLevelDepthCase : public TextureLevelCommonCase
1118{
1119public:
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
1125private:
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
1154class TextureLevelInternalFormatCase : public TextureLevelCase
1155{
1156public:
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
1162private:
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
1194class TextureLevelSizeCase : public TextureLevelCase
1195{
1196public:
1197						TextureLevelSizeCase			(Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type, glw::GLenum pname);
1198
1199private:
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
1207TextureLevelSizeCase::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
1213void TextureLevelSizeCase::generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
1214{
1215	generateInternalFormatTextureGenerationGroup(iterations, m_target);
1216}
1217
1218bool 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
1240int 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
1316class TextureLevelTypeCase : public TextureLevelCase
1317{
1318public:
1319						TextureLevelTypeCase			(Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type, glw::GLenum pname);
1320
1321private:
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
1329TextureLevelTypeCase::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
1335void TextureLevelTypeCase::generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
1336{
1337	generateInternalFormatTextureGenerationGroup(iterations, m_target);
1338}
1339
1340bool 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
1362int 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
1457class TextureLevelCompressedCase : public TextureLevelCase
1458{
1459public:
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
1465private:
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
1494class TextureLevelBufferDataStoreCase : public TextureLevelCase
1495{
1496public:
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
1502private:
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
1533class TextureLevelBufferDataOffsetCase : public TextureLevelCase
1534{
1535public:
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
1541private:
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
1574class TextureLevelBufferDataSizeCase : public TextureLevelCase
1575{
1576public:
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
1582private:
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
1617static 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
1629TextureLevelStateQueryTests::TextureLevelStateQueryTests (Context& context)
1630	: TestCaseGroup(context, "texture_level", "GetTexLevelParameter tests")
1631{
1632}
1633
1634TextureLevelStateQueryTests::~TextureLevelStateQueryTests (void)
1635{
1636}
1637
1638void 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