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