• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.1 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Shader built-in constant tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es31fShaderBuiltinConstantTests.hpp"
25 #include "glsShaderExecUtil.hpp"
26 #include "deUniquePtr.hpp"
27 #include "deStringUtil.hpp"
28 #include "tcuTestLog.hpp"
29 #include "gluStrUtil.hpp"
30 #include "gluContextInfo.hpp"
31 #include "glwEnums.hpp"
32 #include "glwFunctions.hpp"
33 
34 using std::string;
35 using std::vector;
36 using tcu::TestLog;
37 
38 namespace deqp
39 {
40 namespace gles31
41 {
42 namespace Functional
43 {
44 namespace
45 {
46 
getInteger(const glw::Functions & gl,deUint32 pname)47 static int getInteger (const glw::Functions& gl, deUint32 pname)
48 {
49 	int value = -1;
50 	gl.getIntegerv(pname, &value);
51 	GLU_EXPECT_NO_ERROR(gl.getError(), ("glGetIntegerv(" + glu::getGettableStateStr((int)pname).toString() + ")").c_str());
52 	return value;
53 }
54 
55 template<deUint32 Pname>
getInteger(const glw::Functions & gl)56 static int getInteger (const glw::Functions& gl)
57 {
58 	return getInteger(gl, Pname);
59 }
60 
getVectorsFromComps(const glw::Functions & gl,deUint32 pname)61 static int getVectorsFromComps (const glw::Functions& gl, deUint32 pname)
62 {
63 	int value = -1;
64 	gl.getIntegerv(pname, &value);
65 	GLU_EXPECT_NO_ERROR(gl.getError(), ("glGetIntegerv(" + glu::getGettableStateStr((int)pname).toString() + ")").c_str());
66 	TCU_CHECK_MSG(value%4 == 0, ("Expected " + glu::getGettableStateStr((int)pname).toString() + " to be divisible by 4").c_str());
67 	return value/4;
68 }
69 
70 template<deUint32 Pname>
getVectorsFromComps(const glw::Functions & gl)71 static int getVectorsFromComps (const glw::Functions& gl)
72 {
73 	return getVectorsFromComps(gl, Pname);
74 }
75 
getIVec3(const glw::Functions & gl,deUint32 pname)76 static tcu::IVec3 getIVec3 (const glw::Functions& gl, deUint32 pname)
77 {
78 	tcu::IVec3 value(-1);
79 	for (int ndx = 0; ndx < 3; ndx++)
80 		gl.getIntegeri_v(pname, (glw::GLuint)ndx, &value[ndx]);
81 	GLU_EXPECT_NO_ERROR(gl.getError(), ("glGetIntegeri_v(" + glu::getGettableStateStr((int)pname).toString() + ")").c_str());
82 	return value;
83 }
84 
85 template<deUint32 Pname>
getIVec3(const glw::Functions & gl)86 static tcu::IVec3 getIVec3 (const glw::Functions& gl)
87 {
88 	return getIVec3(gl, Pname);
89 }
90 
makeCaseName(const std::string & varName)91 static std::string makeCaseName (const std::string& varName)
92 {
93 	DE_ASSERT(varName.length() > 3);
94 	DE_ASSERT(varName.substr(0,3) == "gl_");
95 
96 	std::ostringstream name;
97 	name << de::toLower(char(varName[3]));
98 
99 	for (size_t ndx = 4; ndx < varName.length(); ndx++)
100 	{
101 		const char c = char(varName[ndx]);
102 		if (de::isUpper(c))
103 			name << '_' << de::toLower(c);
104 		else
105 			name << c;
106 	}
107 
108 	return name.str();
109 }
110 
111 enum
112 {
113 	VS = (1<<glu::SHADERTYPE_VERTEX),
114 	TC = (1<<glu::SHADERTYPE_TESSELLATION_CONTROL),
115 	TE = (1<<glu::SHADERTYPE_TESSELLATION_EVALUATION),
116 	GS = (1<<glu::SHADERTYPE_GEOMETRY),
117 	FS = (1<<glu::SHADERTYPE_FRAGMENT),
118 	CS = (1<<glu::SHADERTYPE_COMPUTE),
119 
120 	SHADER_TYPES = VS|TC|TE|GS|FS|CS
121 };
122 
123 template<typename DataType>
124 class ShaderBuiltinConstantCase : public TestCase
125 {
126 public:
127 	typedef DataType (*GetConstantValueFunc) (const glw::Functions& gl);
128 
129 								ShaderBuiltinConstantCase	(Context& context, const char* varName, GetConstantValueFunc getValue, const char* requiredExt);
130 								~ShaderBuiltinConstantCase	(void);
131 
132 	void						init						(void);
133 	IterateResult				iterate						(void);
134 
135 private:
136 	bool						verifyInShaderType			(glu::ShaderType shaderType, DataType reference);
137 
138 	const std::string			m_varName;
139 	const GetConstantValueFunc	m_getValue;
140 	const std::string			m_requiredExt;
141 };
142 
143 template<typename DataType>
ShaderBuiltinConstantCase(Context & context,const char * varName,GetConstantValueFunc getValue,const char * requiredExt)144 ShaderBuiltinConstantCase<DataType>::ShaderBuiltinConstantCase (Context& context, const char* varName, GetConstantValueFunc getValue, const char* requiredExt)
145 	: TestCase		(context, makeCaseName(varName).c_str(), varName)
146 	, m_varName		(varName)
147 	, m_getValue	(getValue)
148 	, m_requiredExt	(requiredExt ? requiredExt : "")
149 {
150 	DE_ASSERT(!requiredExt == m_requiredExt.empty());
151 }
152 
153 template<typename DataType>
~ShaderBuiltinConstantCase(void)154 ShaderBuiltinConstantCase<DataType>::~ShaderBuiltinConstantCase (void)
155 {
156 }
157 
158 template<typename DataType>
init(void)159 void ShaderBuiltinConstantCase<DataType>::init (void)
160 {
161 	const bool supportsES32orGL45 = contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
162 									contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5));
163 
164 	if(!glu::isContextTypeES(m_context.getRenderContext().getType()))
165 	{
166 		if(m_varName == "gl_MaxVertexOutputVectors" || m_varName == "gl_MaxFragmentInputVectors")
167 		{
168 			std::string message = "The test requires a GLES context. The constant '" + m_varName + "' is not supported.";
169 			TCU_THROW(NotSupportedError, message.c_str());
170 		}
171 	}
172 
173 	if (m_requiredExt == "GL_OES_sample_variables" || m_requiredExt == "GL_EXT_geometry_shader" || m_requiredExt == "GL_EXT_tessellation_shader")
174 	{
175 		if(!supportsES32orGL45)
176 		{
177 			const std::string message = "The test requires a GLES 3.2 or GL 4.5 context or support for the extension " + m_requiredExt + ".";
178 			TCU_CHECK_AND_THROW(NotSupportedError, m_context.getContextInfo().isExtensionSupported(m_requiredExt.c_str()), message.c_str());
179 		}
180 	}
181 	else if (!m_requiredExt.empty() && !m_context.getContextInfo().isExtensionSupported(m_requiredExt.c_str()))
182 			throw tcu::NotSupportedError(m_requiredExt + " not supported");
183 
184 	if (!supportsES32orGL45 && (m_varName == "gl_MaxTessControlImageUniforms"	||
185 		m_varName == "gl_MaxTessEvaluationImageUniforms"			||
186 		m_varName == "gl_MaxTessControlAtomicCounters"				||
187 		m_varName == "gl_MaxTessEvaluationAtomicCounters"			||
188 		m_varName == "gl_MaxTessControlAtomicCounterBuffers"		||
189 		m_varName == "gl_MaxTessEvaluationAtomicCounterBuffers"))
190 	{
191 		std::string message = "The test requires a GLES 3.2 or GL 4.5 context. The constant '" + m_varName + "' is not supported.";
192 		TCU_THROW(NotSupportedError, message.c_str());
193 	}
194 }
195 
createGetConstantExecutor(const glu::RenderContext & renderCtx,glu::ShaderType shaderType,glu::DataType dataType,const std::string & varName,const std::string & extName)196 static gls::ShaderExecUtil::ShaderExecutor* createGetConstantExecutor (const glu::RenderContext&	renderCtx,
197 																	   glu::ShaderType				shaderType,
198 																	   glu::DataType				dataType,
199 																	   const std::string&			varName,
200 																	   const std::string&			extName)
201 {
202 	using namespace gls::ShaderExecUtil;
203 
204 	const bool	supportsES32orGL45	= contextSupports(renderCtx.getType(), glu::ApiType::es(3, 2)) ||
205 									  contextSupports(renderCtx.getType(), glu::ApiType::core(4, 5));
206 	ShaderSpec	shaderSpec;
207 
208 	shaderSpec.version	= glu::getContextTypeGLSLVersion(renderCtx.getType());
209 	shaderSpec.source	= string("result = ") + varName + ";\n";
210 
211 	shaderSpec.outputs.push_back(Symbol("result", glu::VarType(dataType, glu::PRECISION_HIGHP)));
212 
213 	if (!extName.empty() && !(supportsES32orGL45 && (extName == "GL_OES_sample_variables" || extName == "GL_EXT_geometry_shader" || extName == "GL_EXT_tessellation_shader")))
214 		shaderSpec.globalDeclarations = "#extension " + extName + " : require\n";
215 
216 	return createExecutor(renderCtx, shaderType, shaderSpec);
217 }
218 
219 template<typename DataType>
logVarValue(tcu::TestLog & log,const std::string & varName,DataType value)220 static void logVarValue (tcu::TestLog& log, const std::string& varName, DataType value)
221 {
222 	log << TestLog::Message << varName << " = " << value << TestLog::EndMessage;
223 }
224 
225 template<>
logVarValue(tcu::TestLog & log,const std::string & varName,int value)226 void logVarValue<int> (tcu::TestLog& log, const std::string& varName, int value)
227 {
228 	log << TestLog::Integer(varName, varName, "", QP_KEY_TAG_NONE, value);
229 }
230 
231 template<typename DataType>
verifyInShaderType(glu::ShaderType shaderType,DataType reference)232 bool ShaderBuiltinConstantCase<DataType>::verifyInShaderType (glu::ShaderType shaderType, DataType reference)
233 {
234 	using namespace gls::ShaderExecUtil;
235 
236 	const de::UniquePtr<ShaderExecutor>	shaderExecutor	(createGetConstantExecutor(m_context.getRenderContext(), shaderType, glu::dataTypeOf<DataType>(), m_varName, m_requiredExt));
237 	DataType							result			= DataType(-1);
238 	void* const							outputs			= &result;
239 
240 	if (!shaderExecutor->isOk())
241 	{
242 		shaderExecutor->log(m_testCtx.getLog());
243 		TCU_FAIL("Compile failed");
244 	}
245 
246 	shaderExecutor->useProgram();
247 	shaderExecutor->execute(1, DE_NULL, &outputs);
248 
249 	logVarValue(m_testCtx.getLog(), m_varName, result);
250 
251 	if (result != reference)
252 	{
253 		m_testCtx.getLog() << TestLog::Message << "ERROR: Expected " << m_varName << " = " << reference << TestLog::EndMessage
254 						   << TestLog::Message << "Test shader:" << TestLog::EndMessage;
255 		shaderExecutor->log(m_testCtx.getLog());
256 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid builtin constant value");
257 		return false;
258 	}
259 	else
260 		return true;
261 }
262 
263 template<typename DataType>
iterate(void)264 TestCase::IterateResult ShaderBuiltinConstantCase<DataType>::iterate (void)
265 {
266 	const DataType	reference	= m_getValue(m_context.getRenderContext().getFunctions());
267 
268 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
269 
270 	for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; shaderType++)
271 	{
272 		if ((SHADER_TYPES & (1<<shaderType)) != 0)
273 		{
274 			const char* const			shaderTypeName	= glu::getShaderTypeName(glu::ShaderType(shaderType));
275 			const tcu::ScopedLogSection	section			(m_testCtx.getLog(), shaderTypeName, shaderTypeName);
276 
277 			try
278 			{
279 				const bool isOk = verifyInShaderType(glu::ShaderType(shaderType), reference);
280 				DE_ASSERT(isOk || m_testCtx.getTestResult() != QP_TEST_RESULT_PASS);
281 				DE_UNREF(isOk);
282 			}
283 			catch (const tcu::NotSupportedError& e)
284 			{
285 				m_testCtx.getLog() << TestLog::Message << "Not checking " << shaderTypeName << ": " << e.what() << TestLog::EndMessage;
286 			}
287 			catch (const tcu::TestError& e)
288 			{
289 				m_testCtx.getLog() << TestLog::Message << e.what() << TestLog::EndMessage;
290 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, e.getMessage());
291 			}
292 		}
293 	}
294 
295 	return STOP;
296 }
297 
298 } // anonymous
299 
ShaderBuiltinConstantTests(Context & context)300 ShaderBuiltinConstantTests::ShaderBuiltinConstantTests (Context& context)
301 	: TestCaseGroup(context, "builtin_constants", "Built-in Constant Tests")
302 {
303 }
304 
~ShaderBuiltinConstantTests(void)305 ShaderBuiltinConstantTests::~ShaderBuiltinConstantTests (void)
306 {
307 }
308 
init(void)309 void ShaderBuiltinConstantTests::init (void)
310 {
311 	// Core builtin constants
312 	{
313 		static const struct
314 		{
315 			const char*												varName;
316 			ShaderBuiltinConstantCase<int>::GetConstantValueFunc	getValue;
317 		} intConstants[] =
318 		{
319 			{ "gl_MaxVertexAttribs",					getInteger<GL_MAX_VERTEX_ATTRIBS>						},
320 			{ "gl_MaxVertexUniformVectors",				getInteger<GL_MAX_VERTEX_UNIFORM_VECTORS>				},
321 			{ "gl_MaxVertexOutputVectors",				getVectorsFromComps<GL_MAX_VERTEX_OUTPUT_COMPONENTS>	},
322 			{ "gl_MaxFragmentInputVectors",				getVectorsFromComps<GL_MAX_FRAGMENT_INPUT_COMPONENTS>	},
323 			{ "gl_MaxFragmentUniformVectors",			getInteger<GL_MAX_FRAGMENT_UNIFORM_VECTORS>				},
324 			{ "gl_MaxDrawBuffers",						getInteger<GL_MAX_DRAW_BUFFERS>							},
325 
326 			{ "gl_MaxVertexTextureImageUnits",			getInteger<GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS>			},
327 			{ "gl_MaxCombinedTextureImageUnits",		getInteger<GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS>			},
328 			{ "gl_MaxTextureImageUnits",				getInteger<GL_MAX_TEXTURE_IMAGE_UNITS>					},
329 
330 			{ "gl_MinProgramTexelOffset",				getInteger<GL_MIN_PROGRAM_TEXEL_OFFSET>					},
331 			{ "gl_MaxProgramTexelOffset",				getInteger<GL_MAX_PROGRAM_TEXEL_OFFSET>					},
332 
333 			{ "gl_MaxImageUnits",						getInteger<GL_MAX_IMAGE_UNITS>							},
334 			{ "gl_MaxVertexImageUniforms",				getInteger<GL_MAX_VERTEX_IMAGE_UNIFORMS>				},
335 			{ "gl_MaxFragmentImageUniforms",			getInteger<GL_MAX_FRAGMENT_IMAGE_UNIFORMS>				},
336 			{ "gl_MaxComputeImageUniforms",				getInteger<GL_MAX_COMPUTE_IMAGE_UNIFORMS>				},
337 			{ "gl_MaxCombinedImageUniforms",			getInteger<GL_MAX_COMBINED_IMAGE_UNIFORMS>				},
338 
339 			{ "gl_MaxCombinedShaderOutputResources",	getInteger<GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES>		},
340 
341 			{ "gl_MaxComputeUniformComponents",			getInteger<GL_MAX_COMPUTE_UNIFORM_COMPONENTS>			},
342 			{ "gl_MaxComputeTextureImageUnits",			getInteger<GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS>			},
343 
344 			{ "gl_MaxComputeAtomicCounters",			getInteger<GL_MAX_COMPUTE_ATOMIC_COUNTERS>				},
345 			{ "gl_MaxComputeAtomicCounterBuffers",		getInteger<GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS>		},
346 
347 			{ "gl_MaxVertexAtomicCounters",				getInteger<GL_MAX_VERTEX_ATOMIC_COUNTERS>				},
348 			{ "gl_MaxFragmentAtomicCounters",			getInteger<GL_MAX_FRAGMENT_ATOMIC_COUNTERS>				},
349 			{ "gl_MaxCombinedAtomicCounters",			getInteger<GL_MAX_COMBINED_ATOMIC_COUNTERS>				},
350 			{ "gl_MaxAtomicCounterBindings",			getInteger<GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS>		},
351 
352 			{ "gl_MaxVertexAtomicCounterBuffers",		getInteger<GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS>		},
353 			{ "gl_MaxFragmentAtomicCounterBuffers",		getInteger<GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS>		},
354 			{ "gl_MaxCombinedAtomicCounterBuffers",		getInteger<GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS>		},
355 			{ "gl_MaxAtomicCounterBufferSize",			getInteger<GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE>			},
356 		};
357 
358 		static const struct
359 		{
360 			const char*													varName;
361 			ShaderBuiltinConstantCase<tcu::IVec3>::GetConstantValueFunc	getValue;
362 		} ivec3Constants[] =
363 		{
364 			{ "gl_MaxComputeWorkGroupCount",			getIVec3<GL_MAX_COMPUTE_WORK_GROUP_COUNT>				},
365 			{ "gl_MaxComputeWorkGroupSize",				getIVec3<GL_MAX_COMPUTE_WORK_GROUP_SIZE>				},
366 		};
367 
368 		tcu::TestCaseGroup* const coreGroup = new tcu::TestCaseGroup(m_testCtx, "core", "Core Specification");
369 		addChild(coreGroup);
370 
371 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(intConstants); ndx++)
372 			coreGroup->addChild(new ShaderBuiltinConstantCase<int>(m_context, intConstants[ndx].varName, intConstants[ndx].getValue, DE_NULL));
373 
374 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(ivec3Constants); ndx++)
375 			coreGroup->addChild(new ShaderBuiltinConstantCase<tcu::IVec3>(m_context, ivec3Constants[ndx].varName, ivec3Constants[ndx].getValue, DE_NULL));
376 	}
377 
378 	// OES_sample_variables
379 	{
380 		tcu::TestCaseGroup* const sampleVarGroup = new tcu::TestCaseGroup(m_testCtx, "sample_variables", "GL_OES_sample_variables");
381 		addChild(sampleVarGroup);
382 		sampleVarGroup->addChild(new ShaderBuiltinConstantCase<int>(m_context, "gl_MaxSamples", getInteger<GL_MAX_SAMPLES>, "GL_OES_sample_variables"));
383 	}
384 
385 	// EXT_geometry_shader
386 	{
387 		static const struct
388 		{
389 			const char*												varName;
390 			ShaderBuiltinConstantCase<int>::GetConstantValueFunc	getValue;
391 		} intConstants[] =
392 		{
393 			{ "gl_MaxGeometryInputComponents",			getInteger<GL_MAX_GEOMETRY_INPUT_COMPONENTS>			},
394 			{ "gl_MaxGeometryOutputComponents",			getInteger<GL_MAX_GEOMETRY_OUTPUT_COMPONENTS>			},
395 			{ "gl_MaxGeometryImageUniforms",			getInteger<GL_MAX_GEOMETRY_IMAGE_UNIFORMS>				},
396 			{ "gl_MaxGeometryTextureImageUnits",		getInteger<GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS>			},
397 			{ "gl_MaxGeometryOutputVertices",			getInteger<GL_MAX_GEOMETRY_OUTPUT_VERTICES>				},
398 			{ "gl_MaxGeometryTotalOutputComponents",	getInteger<GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS>		},
399 			{ "gl_MaxGeometryUniformComponents",		getInteger<GL_MAX_GEOMETRY_UNIFORM_COMPONENTS>			},
400 			{ "gl_MaxGeometryAtomicCounters",			getInteger<GL_MAX_GEOMETRY_ATOMIC_COUNTERS>				},
401 			{ "gl_MaxGeometryAtomicCounterBuffers",		getInteger<GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS>		},
402 		};
403 
404 		tcu::TestCaseGroup* const geomGroup = new tcu::TestCaseGroup(m_testCtx, "geometry_shader", "GL_EXT_geometry_shader");
405 		addChild(geomGroup);
406 
407 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(intConstants); ndx++)
408 			geomGroup->addChild(new ShaderBuiltinConstantCase<int>(m_context, intConstants[ndx].varName, intConstants[ndx].getValue, "GL_EXT_geometry_shader"));
409 	}
410 
411 	// EXT_tessellation_shader
412 	{
413 		static const struct
414 		{
415 			const char*												varName;
416 			ShaderBuiltinConstantCase<int>::GetConstantValueFunc	getValue;
417 		} intConstants[] =
418 		{
419 			{ "gl_MaxTessControlInputComponents",			getInteger<GL_MAX_TESS_CONTROL_INPUT_COMPONENTS>			},
420 			{ "gl_MaxTessControlOutputComponents",			getInteger<GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS>			},
421 			{ "gl_MaxTessControlTextureImageUnits",			getInteger<GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS>			},
422 			{ "gl_MaxTessControlUniformComponents",			getInteger<GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS>			},
423 			{ "gl_MaxTessControlTotalOutputComponents",		getInteger<GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS>		},
424 
425 			{ "gl_MaxTessControlImageUniforms",				getInteger<GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS>				},
426 			{ "gl_MaxTessEvaluationImageUniforms",			getInteger<GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS>			},
427 			{ "gl_MaxTessControlAtomicCounters",			getInteger<GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS>				},
428 			{ "gl_MaxTessEvaluationAtomicCounters",			getInteger<GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS>			},
429 			{ "gl_MaxTessControlAtomicCounterBuffers",		getInteger<GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS>		},
430 			{ "gl_MaxTessEvaluationAtomicCounterBuffers",	getInteger<GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS>	},
431 
432 			{ "gl_MaxTessEvaluationInputComponents",		getInteger<GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS>			},
433 			{ "gl_MaxTessEvaluationOutputComponents",		getInteger<GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS>		},
434 			{ "gl_MaxTessEvaluationTextureImageUnits",		getInteger<GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS>		},
435 			{ "gl_MaxTessEvaluationUniformComponents",		getInteger<GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS>		},
436 
437 			{ "gl_MaxTessPatchComponents",					getInteger<GL_MAX_TESS_PATCH_COMPONENTS>					},
438 
439 			{ "gl_MaxPatchVertices",						getInteger<GL_MAX_PATCH_VERTICES>							},
440 			{ "gl_MaxTessGenLevel",							getInteger<GL_MAX_TESS_GEN_LEVEL>							},
441 		};
442 
443 		tcu::TestCaseGroup* const tessGroup = new tcu::TestCaseGroup(m_testCtx, "tessellation_shader", "GL_EXT_tessellation_shader");
444 		addChild(tessGroup);
445 
446 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(intConstants); ndx++)
447 			tessGroup->addChild(new ShaderBuiltinConstantCase<int>(m_context, intConstants[ndx].varName, intConstants[ndx].getValue, "GL_EXT_tessellation_shader"));
448 	}
449 }
450 
451 } // Functional
452 } // gles31
453 } // deqp
454