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