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