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