• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.1 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Texture level state query tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es31fTextureLevelStateQueryTests.hpp"
25 #include "glsStateQueryUtil.hpp"
26 #include "tcuTestLog.hpp"
27 #include "gluRenderContext.hpp"
28 #include "gluCallLogWrapper.hpp"
29 #include "gluTextureUtil.hpp"
30 #include "gluStrUtil.hpp"
31 #include "gluContextInfo.hpp"
32 #include "glwFunctions.hpp"
33 #include "glwEnums.hpp"
34 #include "tcuTextureUtil.hpp"
35 #include "tcuFormatUtil.hpp"
36 #include "deStringUtil.hpp"
37 #include "deUniquePtr.hpp"
38 
39 namespace deqp
40 {
41 namespace gles31
42 {
43 namespace Functional
44 {
45 namespace
46 {
47 
48 using namespace gls::StateQueryUtil;
49 
50 
textureTypeHasDepth(glw::GLenum textureBindTarget)51 static bool textureTypeHasDepth (glw::GLenum textureBindTarget)
52 {
53 	switch (textureBindTarget)
54 	{
55 		case GL_TEXTURE_2D:						return false;
56 		case GL_TEXTURE_3D:						return true;
57 		case GL_TEXTURE_2D_ARRAY:				return true;
58 		case GL_TEXTURE_CUBE_MAP:				return false;
59 		case GL_TEXTURE_2D_MULTISAMPLE:			return false;
60 		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:	return true;
61 		case GL_TEXTURE_BUFFER:					return false;
62 		case GL_TEXTURE_CUBE_MAP_ARRAY:			return true;
63 		default:
64 			DE_ASSERT(DE_FALSE);
65 			return false;
66 	}
67 }
68 
textureTypeHasHeight(glw::GLenum textureBindTarget)69 static bool textureTypeHasHeight (glw::GLenum textureBindTarget)
70 {
71 	switch (textureBindTarget)
72 	{
73 		case GL_TEXTURE_2D:						return true;
74 		case GL_TEXTURE_3D:						return true;
75 		case GL_TEXTURE_2D_ARRAY:				return true;
76 		case GL_TEXTURE_CUBE_MAP:				return true;
77 		case GL_TEXTURE_2D_MULTISAMPLE:			return true;
78 		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:	return true;
79 		case GL_TEXTURE_BUFFER:					return false;
80 		case GL_TEXTURE_CUBE_MAP_ARRAY:			return true;
81 		default:
82 			DE_ASSERT(DE_FALSE);
83 			return false;
84 	}
85 }
86 
getTextureTargetExtension(glw::GLenum target)87 static const char* getTextureTargetExtension (glw::GLenum target)
88 {
89 	switch (target)
90 	{
91 		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:	return "GL_OES_texture_storage_multisample_2d_array";
92 		case GL_TEXTURE_BUFFER:					return "GL_EXT_texture_buffer";
93 		case GL_TEXTURE_CUBE_MAP_ARRAY:			return "GL_EXT_texture_cube_map_array";
94 		default:
95 			DE_ASSERT(DE_FALSE);
96 			return DE_NULL;
97 	}
98 }
99 
isCoreTextureTarget(glw::GLenum target,const glu::ContextType & contextType)100 static bool isCoreTextureTarget (glw::GLenum target, const glu::ContextType& contextType)
101 {
102 	switch (target)
103 	{
104 		case GL_TEXTURE_2D:
105 		case GL_TEXTURE_3D:
106 		case GL_TEXTURE_2D_ARRAY:
107 		case GL_TEXTURE_CUBE_MAP:
108 		case GL_TEXTURE_2D_MULTISAMPLE:
109 			return true;
110 
111 		case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
112 		case GL_TEXTURE_BUFFER:
113 		case GL_TEXTURE_CUBE_MAP_ARRAY:
114 			return glu::contextSupports(contextType, glu::ApiType::es(3, 2)) ||
115 				   glu::contextSupports(contextType, glu::ApiType::core(4, 5));
116 
117 		default:
118 			return false;
119 	}
120 }
121 
122 struct 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 
TextureLevelSpecdeqp::gles31::Functional::__anonaaa137970111::TextureGenerationSpec::TextureLevelSpec133 		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 
TextureGenerationSpecdeqp::gles31::Functional::__anonaaa137970111::TextureGenerationSpec155 	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 };
167 struct IntegerPrinter
168 {
getIntegerNamedeqp::gles31::Functional::__anonaaa137970111::IntegerPrinter169 	static std::string	getIntegerName	(int v)		{ return de::toString(v); }
getFloatNamedeqp::gles31::Functional::__anonaaa137970111::IntegerPrinter170 	static std::string	getFloatName	(float v)	{ return de::toString(v); }
171 };
172 
173 struct PixelFormatPrinter
174 {
getIntegerNamedeqp::gles31::Functional::__anonaaa137970111::PixelFormatPrinter175 	static std::string	getIntegerName	(int v)		{ return de::toString(glu::getTextureFormatStr(v));		}
getFloatNamedeqp::gles31::Functional::__anonaaa137970111::PixelFormatPrinter176 	static std::string	getFloatName	(float v)	{ return de::toString(glu::getTextureFormatStr((int)v));	}
177 };
178 
179 template <typename Printer>
verifyTextureLevelParameterEqualWithPrinter(glu::CallLogWrapper & gl,glw::GLenum target,int level,glw::GLenum pname,int refValue,QueryType type)180 static 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 
verifyTextureLevelParameterEqual(glu::CallLogWrapper & gl,glw::GLenum target,int level,glw::GLenum pname,int refValue,QueryType type)196 static 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 
verifyTextureLevelParameterInternalFormatEqual(glu::CallLogWrapper & gl,glw::GLenum target,int level,glw::GLenum pname,int refValue,QueryType type)201 static 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 
verifyTextureLevelParameterGreaterOrEqual(glu::CallLogWrapper & gl,glw::GLenum target,int level,glw::GLenum pname,int refValue,QueryType type)206 static 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 
verifyTextureLevelParameterInternalFormatAnyOf(glu::CallLogWrapper & gl,glw::GLenum target,int level,glw::GLenum pname,const int * refValues,int numRefValues,QueryType type)222 static 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 
isDepthFormat(const tcu::TextureFormat & fmt)273 static bool isDepthFormat (const tcu::TextureFormat& fmt)
274 {
275 	return fmt.order == tcu::TextureFormat::D || fmt.order == tcu::TextureFormat::DS;
276 }
277 
isColorRenderableFormat(glw::GLenum internalFormat)278 static 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 
isRenderableFormat(glw::GLenum internalFormat)310 static 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 
isTextureBufferFormat(glw::GLenum internalFormat)320 static 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 
isLegalFormatForTarget(glw::GLenum target,glw::GLenum format)354 static 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 
isCompressionSupportedForTarget(glw::GLenum target)367 static bool isCompressionSupportedForTarget (glw::GLenum target)
368 {
369 	return target == GL_TEXTURE_2D || target == GL_TEXTURE_2D_ARRAY;
370 }
371 
isMultisampleTarget(glw::GLenum target)372 static bool isMultisampleTarget (glw::GLenum target)
373 {
374 	return target == GL_TEXTURE_2D_MULTISAMPLE || target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
375 }
376 
targetSupportsMipLevels(glw::GLenum target)377 static 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 
getPixelSize(glw::GLenum internalFormat)384 static int getPixelSize (glw::GLenum internalFormat)
385 {
386 	const tcu::TextureFormat fmt = glu::mapGLInternalFormat(internalFormat);
387 	return fmt.getPixelSize();
388 }
389 
generateColorTextureGenerationGroup(std::vector<TextureGenerationSpec> & group,glw::GLenum target,int maxSamples,glw::GLenum internalFormat)390 static 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 
generateInternalFormatTextureGenerationGroup(std::vector<TextureGenerationSpec> & group,glw::GLenum target)589 static 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 
generateCompressedTextureGenerationGroup(std::vector<TextureGenerationSpec> & group,glw::GLenum target)677 static 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 
generateTextureBufferGenerationGroup(std::vector<TextureGenerationSpec> & group,glw::GLenum target)715 static 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 
applyTextureGenerationSpec(glu::CallLogWrapper & gl,const TextureGenerationSpec & spec,glw::GLuint & texBuffer)734 bool 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 
821 class TextureLevelCase : public TestCase
822 {
823 public:
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 
831 protected:
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 
842 private:
843 	int									m_iteration;
844 	std::vector<TextureGenerationSpec>	m_iterations;
845 	bool								m_allIterationsOk;
846 	std::vector<int>					m_failedIterations;
847 };
848 
TextureLevelCase(Context & ctx,const char * name,const char * desc,glw::GLenum target,QueryType type)849 TextureLevelCase::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 
~TextureLevelCase(void)860 TextureLevelCase::~TextureLevelCase (void)
861 {
862 	deinit();
863 }
864 
init(void)865 void 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 
deinit(void)881 void 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 
getFormatSamples(glw::GLenum internalFormat,std::vector<int> & samples)895 void 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 
iterate(void)917 TextureLevelCase::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 
testConfig(const TextureGenerationSpec & spec)950 bool 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  *//*--------------------------------------------------------------------*/
983 class TextureLevelCommonCase : public TextureLevelCase
984 {
985 public:
986 						TextureLevelCommonCase	(Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type);
987 
988 protected:
989 	virtual void		generateTestIterations	(std::vector<TextureGenerationSpec>& iterations);
990 };
991 
TextureLevelCommonCase(Context & ctx,const char * name,const char * desc,glw::GLenum target,QueryType type)992 TextureLevelCommonCase::TextureLevelCommonCase (Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type)
993 	: TextureLevelCase(ctx, name, desc, target, type)
994 {
995 }
996 
generateTestIterations(std::vector<TextureGenerationSpec> & iterations)997 void 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 
1012 class TextureLevelSampleCase : public TextureLevelCommonCase
1013 {
1014 public:
TextureLevelSampleCase(Context & ctx,const char * name,const char * desc,glw::GLenum target,QueryType type)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 
1020 private:
checkTextureState(glu::CallLogWrapper & gl,const TextureGenerationSpec & spec)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 
1030 class TextureLevelFixedSamplesCase : public TextureLevelCommonCase
1031 {
1032 public:
TextureLevelFixedSamplesCase(Context & ctx,const char * name,const char * desc,glw::GLenum target,QueryType type)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 
1038 private:
checkTextureState(glu::CallLogWrapper & gl,const TextureGenerationSpec & spec)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 
1048 class TextureLevelWidthCase : public TextureLevelCommonCase
1049 {
1050 public:
TextureLevelWidthCase(Context & ctx,const char * name,const char * desc,glw::GLenum target,QueryType type)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 
1056 private:
checkTextureState(glu::CallLogWrapper & gl,const TextureGenerationSpec & spec)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 
1084 class TextureLevelHeightCase : public TextureLevelCommonCase
1085 {
1086 public:
TextureLevelHeightCase(Context & ctx,const char * name,const char * desc,glw::GLenum target,QueryType type)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 
1092 private:
checkTextureState(glu::CallLogWrapper & gl,const TextureGenerationSpec & spec)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 
1120 class TextureLevelDepthCase : public TextureLevelCommonCase
1121 {
1122 public:
TextureLevelDepthCase(Context & ctx,const char * name,const char * desc,glw::GLenum target,QueryType type)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 
1128 private:
1129 
checkTextureState(glu::CallLogWrapper & gl,const TextureGenerationSpec & spec)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 
1157 class TextureLevelInternalFormatCase : public TextureLevelCase
1158 {
1159 public:
TextureLevelInternalFormatCase(Context & ctx,const char * name,const char * desc,glw::GLenum target,QueryType type)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 
1165 private:
generateTestIterations(std::vector<TextureGenerationSpec> & iterations)1166 	void generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
1167 	{
1168 		generateInternalFormatTextureGenerationGroup(iterations, m_target);
1169 	}
1170 
checkTextureState(glu::CallLogWrapper & gl,const TextureGenerationSpec & spec)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 
1197 class TextureLevelSizeCase : public TextureLevelCase
1198 {
1199 public:
1200 						TextureLevelSizeCase			(Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type, glw::GLenum pname);
1201 
1202 private:
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 
TextureLevelSizeCase(Context & ctx,const char * name,const char * desc,glw::GLenum target,QueryType type,glw::GLenum pname)1210 TextureLevelSizeCase::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 
generateTestIterations(std::vector<TextureGenerationSpec> & iterations)1216 void TextureLevelSizeCase::generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
1217 {
1218 	generateInternalFormatTextureGenerationGroup(iterations, m_target);
1219 }
1220 
checkTextureState(glu::CallLogWrapper & gl,const TextureGenerationSpec & spec)1221 bool 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 
getMinimumComponentResolution(glw::GLenum internalFormat)1243 int 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 
1319 class TextureLevelTypeCase : public TextureLevelCase
1320 {
1321 public:
1322 						TextureLevelTypeCase			(Context& ctx, const char* name, const char* desc, glw::GLenum target, QueryType type, glw::GLenum pname);
1323 
1324 private:
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 
TextureLevelTypeCase(Context & ctx,const char * name,const char * desc,glw::GLenum target,QueryType type,glw::GLenum pname)1332 TextureLevelTypeCase::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 
generateTestIterations(std::vector<TextureGenerationSpec> & iterations)1338 void TextureLevelTypeCase::generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
1339 {
1340 	generateInternalFormatTextureGenerationGroup(iterations, m_target);
1341 }
1342 
checkTextureState(glu::CallLogWrapper & gl,const TextureGenerationSpec & spec)1343 bool 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 
getComponentType(glw::GLenum internalFormat)1365 int 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 
1460 class TextureLevelCompressedCase : public TextureLevelCase
1461 {
1462 public:
TextureLevelCompressedCase(Context & ctx,const char * name,const char * desc,glw::GLenum target,QueryType type)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 
1468 private:
generateTestIterations(std::vector<TextureGenerationSpec> & iterations)1469 	void generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
1470 	{
1471 		generateCompressedTextureGenerationGroup(iterations, m_target);
1472 	}
1473 
checkTextureState(glu::CallLogWrapper & gl,const TextureGenerationSpec & spec)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 
checkSupport(Context & ctx)1497 static 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 
1505 class TextureLevelBufferDataStoreCase : public TextureLevelCase
1506 {
1507 public:
TextureLevelBufferDataStoreCase(Context & ctx,const char * name,const char * desc,glw::GLenum target,QueryType type)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 
1513 private:
init(void)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 
generateTestIterations(std::vector<TextureGenerationSpec> & iterations)1521 	void generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
1522 	{
1523 		generateTextureBufferGenerationGroup(iterations, m_target);
1524 	}
1525 
checkTextureState(glu::CallLogWrapper & gl,const TextureGenerationSpec & spec)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 
1543 class TextureLevelBufferDataOffsetCase : public TextureLevelCase
1544 {
1545 public:
TextureLevelBufferDataOffsetCase(Context & ctx,const char * name,const char * desc,glw::GLenum target,QueryType type)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 
1551 private:
init(void)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 
generateTestIterations(std::vector<TextureGenerationSpec> & iterations)1559 	void generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
1560 	{
1561 		generateTextureBufferGenerationGroup(iterations, m_target);
1562 	}
1563 
checkTextureState(glu::CallLogWrapper & gl,const TextureGenerationSpec & spec)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 
1583 class TextureLevelBufferDataSizeCase : public TextureLevelCase
1584 {
1585 public:
TextureLevelBufferDataSizeCase(Context & ctx,const char * name,const char * desc,glw::GLenum target,QueryType type)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 
1591 private:
init(void)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 
generateTestIterations(std::vector<TextureGenerationSpec> & iterations)1599 	void generateTestIterations (std::vector<TextureGenerationSpec>& iterations)
1600 	{
1601 		generateTextureBufferGenerationGroup(iterations, m_target);
1602 	}
1603 
checkTextureState(glu::CallLogWrapper & gl,const TextureGenerationSpec & spec)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 
getVerifierSuffix(QueryType type)1625 static 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 
TextureLevelStateQueryTests(Context & context)1637 TextureLevelStateQueryTests::TextureLevelStateQueryTests (Context& context)
1638 	: TestCaseGroup(context, "texture_level", "GetTexLevelParameter tests")
1639 {
1640 }
1641 
~TextureLevelStateQueryTests(void)1642 TextureLevelStateQueryTests::~TextureLevelStateQueryTests (void)
1643 {
1644 }
1645 
init(void)1646 void 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