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