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