1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 Module
3 * -------------------------------------------------
4 *
5 * Copyright 2015 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 Program State Query tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "es31fProgramStateQueryTests.hpp"
25 #include "es31fInfoLogQueryShared.hpp"
26 #include "glsStateQueryUtil.hpp"
27 #include "gluRenderContext.hpp"
28 #include "gluCallLogWrapper.hpp"
29 #include "gluContextInfo.hpp"
30 #include "gluObjectWrapper.hpp"
31 #include "gluShaderProgram.hpp"
32 #include "glwFunctions.hpp"
33 #include "glwEnums.hpp"
34
35 namespace deqp
36 {
37 namespace gles31
38 {
39 namespace Functional
40 {
41 namespace
42 {
43
44 using namespace gls::StateQueryUtil;
45
getVerifierSuffix(QueryType type)46 static const char* getVerifierSuffix (QueryType type)
47 {
48 switch (type)
49 {
50 case QUERY_PROGRAM_INTEGER_VEC3:
51 case QUERY_PROGRAM_INTEGER:
52 return "get_programiv";
53
54 default:
55 DE_ASSERT(DE_FALSE);
56 return DE_NULL;
57 }
58 }
59
60 class ProgramSeparableCase : public TestCase
61 {
62 public:
63 ProgramSeparableCase (Context& context, QueryType verifier, const char* name, const char* desc);
64 IterateResult iterate (void);
65
66 private:
67 const QueryType m_verifier;
68 };
69
ProgramSeparableCase(Context & context,QueryType verifier,const char * name,const char * desc)70 ProgramSeparableCase::ProgramSeparableCase (Context& context, QueryType verifier, const char* name, const char* desc)
71 : TestCase (context, name, desc)
72 , m_verifier (verifier)
73 {
74 }
75
iterate(void)76 ProgramSeparableCase::IterateResult ProgramSeparableCase::iterate (void)
77 {
78 static const char* const s_vertexSource = "#version 310 es\n"
79 "out highp vec4 v_color;\n"
80 "void main()\n"
81 "{\n"
82 " gl_Position = vec4(float(gl_VertexID) * 0.5, float(gl_VertexID+1) * 0.5, 0.0, 1.0);\n"
83 " v_color = vec4(float(gl_VertexID), 1.0, 0.0, 1.0);\n"
84 "}\n";
85 static const char* const s_fragmentSource = "#version 310 es\n"
86 "in highp vec4 v_color;\n"
87 "layout(location=0) out highp vec4 o_color;\n"
88 "void main()\n"
89 "{\n"
90 " o_color = v_color;\n"
91 "}\n";
92
93 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
94 tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: ");
95 glu::Shader vtxShader (m_context.getRenderContext(), glu::SHADERTYPE_VERTEX);
96 glu::Shader frgShader (m_context.getRenderContext(), glu::SHADERTYPE_FRAGMENT);
97
98 vtxShader.setSources(1, &s_vertexSource, DE_NULL);
99 frgShader.setSources(1, &s_fragmentSource, DE_NULL);
100
101 vtxShader.compile();
102 frgShader.compile();
103
104 {
105 const tcu::ScopedLogSection section(m_testCtx.getLog(), "VtxShader", "Vertex shader");
106 m_testCtx.getLog() << vtxShader;
107 }
108
109 {
110 const tcu::ScopedLogSection section(m_testCtx.getLog(), "FrgShader", "Fragment shader");
111 m_testCtx.getLog() << frgShader;
112 }
113
114 if (!vtxShader.getCompileStatus() || !frgShader.getCompileStatus())
115 throw tcu::TestError("failed to build shaders");
116
117 gl.enableLogging(true);
118
119 {
120 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Initial", "Initial");
121 glu::Program program (m_context.getRenderContext());
122
123 verifyStateProgramInteger(result, gl, program.getProgram(), GL_PROGRAM_SEPARABLE, 0, m_verifier);
124 }
125
126 {
127 const tcu::ScopedLogSection section (m_testCtx.getLog(), "SetFalse", "SetFalse");
128 glu::Program program (m_context.getRenderContext());
129 int linkStatus = 0;
130
131 gl.glAttachShader(program.getProgram(), vtxShader.getShader());
132 gl.glAttachShader(program.getProgram(), frgShader.getShader());
133 gl.glProgramParameteri(program.getProgram(), GL_PROGRAM_SEPARABLE, GL_FALSE);
134 gl.glLinkProgram(program.getProgram());
135 GLU_EXPECT_NO_ERROR(gl.glGetError(), "setup program");
136
137 gl.glGetProgramiv(program.getProgram(), GL_LINK_STATUS, &linkStatus);
138 GLU_EXPECT_NO_ERROR(gl.glGetError(), "query link status");
139
140 if (linkStatus == GL_FALSE)
141 throw tcu::TestError("failed to link program");
142
143 verifyStateProgramInteger(result, gl, program.getProgram(), GL_PROGRAM_SEPARABLE, 0, m_verifier);
144 }
145
146 {
147 const tcu::ScopedLogSection section (m_testCtx.getLog(), "SetTrue", "SetTrue");
148 glu::Program program (m_context.getRenderContext());
149 int linkStatus = 0;
150
151 gl.glAttachShader(program.getProgram(), vtxShader.getShader());
152 gl.glAttachShader(program.getProgram(), frgShader.getShader());
153 gl.glProgramParameteri(program.getProgram(), GL_PROGRAM_SEPARABLE, GL_TRUE);
154 gl.glLinkProgram(program.getProgram());
155 GLU_EXPECT_NO_ERROR(gl.glGetError(), "setup program");
156
157 gl.glGetProgramiv(program.getProgram(), GL_LINK_STATUS, &linkStatus);
158 GLU_EXPECT_NO_ERROR(gl.glGetError(), "query link status");
159
160 if (linkStatus == GL_FALSE)
161 throw tcu::TestError("failed to link program");
162
163 verifyStateProgramInteger(result, gl, program.getProgram(), GL_PROGRAM_SEPARABLE, GL_TRUE, m_verifier);
164 }
165
166 result.setTestContextResult(m_testCtx);
167 return STOP;
168 }
169
170 class ComputeWorkGroupSizeCase : public TestCase
171 {
172 public:
173 ComputeWorkGroupSizeCase (Context& context, QueryType verifier, const char* name, const char* desc);
174 IterateResult iterate (void);
175
176 private:
177 const QueryType m_verifier;
178 };
179
ComputeWorkGroupSizeCase(Context & context,QueryType verifier,const char * name,const char * desc)180 ComputeWorkGroupSizeCase::ComputeWorkGroupSizeCase (Context& context, QueryType verifier, const char* name, const char* desc)
181 : TestCase (context, name, desc)
182 , m_verifier (verifier)
183 {
184 }
185
iterate(void)186 ComputeWorkGroupSizeCase::IterateResult ComputeWorkGroupSizeCase::iterate (void)
187 {
188 static const char* const s_computeSource1D = "#version 310 es\n"
189 "layout (local_size_x = 3) in;\n"
190 "layout(binding = 0) buffer Output\n"
191 "{\n"
192 " highp float val;\n"
193 "} sb_out;\n"
194 "\n"
195 "void main (void)\n"
196 "{\n"
197 " sb_out.val = 1.0;\n"
198 "}\n";
199 static const char* const s_computeSource2D = "#version 310 es\n"
200 "layout (local_size_x = 3, local_size_y = 2) in;\n"
201 "layout(binding = 0) buffer Output\n"
202 "{\n"
203 " highp float val;\n"
204 "} sb_out;\n"
205 "\n"
206 "void main (void)\n"
207 "{\n"
208 " sb_out.val = 1.0;\n"
209 "}\n";
210 static const char* const s_computeSource3D = "#version 310 es\n"
211 "layout (local_size_x = 3, local_size_y = 2, local_size_z = 4) in;\n"
212 "layout(binding = 0) buffer Output\n"
213 "{\n"
214 " highp float val;\n"
215 "} sb_out;\n"
216 "\n"
217 "void main (void)\n"
218 "{\n"
219 " sb_out.val = 1.0;\n"
220 "}\n";
221
222 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
223 tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: ");
224
225 gl.enableLogging(true);
226
227 {
228 const tcu::ScopedLogSection section (m_testCtx.getLog(), "OneDimensional", "1D");
229 glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(s_computeSource1D));
230
231 m_testCtx.getLog() << program;
232 if (!program.isOk())
233 throw tcu::TestError("failed to build program");
234
235 verifyStateProgramIntegerVec3(result, gl, program.getProgram(), GL_COMPUTE_WORK_GROUP_SIZE, tcu::IVec3(3, 1, 1), m_verifier);
236 }
237
238 {
239 const tcu::ScopedLogSection section (m_testCtx.getLog(), "TwoDimensional", "2D");
240 glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(s_computeSource2D));
241
242 m_testCtx.getLog() << program;
243 if (!program.isOk())
244 throw tcu::TestError("failed to build program");
245
246 verifyStateProgramIntegerVec3(result, gl, program.getProgram(), GL_COMPUTE_WORK_GROUP_SIZE, tcu::IVec3(3, 2, 1), m_verifier);
247 }
248
249 {
250 const tcu::ScopedLogSection section (m_testCtx.getLog(), "TreeDimensional", "3D");
251 glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(s_computeSource3D));
252
253 m_testCtx.getLog() << program;
254 if (!program.isOk())
255 throw tcu::TestError("failed to build program");
256
257 verifyStateProgramIntegerVec3(result, gl, program.getProgram(), GL_COMPUTE_WORK_GROUP_SIZE, tcu::IVec3(3, 2, 4), m_verifier);
258 }
259
260 result.setTestContextResult(m_testCtx);
261 return STOP;
262 }
263
264 class ActiveAtomicCounterBuffersCase : public TestCase
265 {
266 public:
267 ActiveAtomicCounterBuffersCase (Context& context, QueryType verifier, const char* name, const char* desc);
268 IterateResult iterate (void);
269
270 private:
271 const QueryType m_verifier;
272 };
273
ActiveAtomicCounterBuffersCase(Context & context,QueryType verifier,const char * name,const char * desc)274 ActiveAtomicCounterBuffersCase::ActiveAtomicCounterBuffersCase (Context& context, QueryType verifier, const char* name, const char* desc)
275 : TestCase (context, name, desc)
276 , m_verifier (verifier)
277 {
278 }
279
iterate(void)280 ActiveAtomicCounterBuffersCase::IterateResult ActiveAtomicCounterBuffersCase::iterate (void)
281 {
282 static const char* const s_computeSource0 = "#version 310 es\n"
283 "layout (local_size_x = 3) in;\n"
284 "layout(binding = 0) buffer Output\n"
285 "{\n"
286 " highp float val;\n"
287 "} sb_out;\n"
288 "\n"
289 "void main (void)\n"
290 "{\n"
291 " sb_out.val = 1.0;\n"
292 "}\n";
293 static const char* const s_computeSource1 = "#version 310 es\n"
294 "layout (local_size_x = 3) in;\n"
295 "layout(binding = 0) uniform highp atomic_uint u_counters[2];\n"
296 "layout(binding = 0) buffer Output\n"
297 "{\n"
298 " highp float val;\n"
299 "} sb_out;\n"
300 "\n"
301 "void main (void)\n"
302 "{\n"
303 " sb_out.val = float(atomicCounterIncrement(u_counters[0])) + float(atomicCounterIncrement(u_counters[1]));\n"
304 "}\n";
305
306 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
307 tcu::ResultCollector result (m_testCtx.getLog(), " // ERROR: ");
308
309 gl.enableLogging(true);
310
311 {
312 const tcu::ScopedLogSection section (m_testCtx.getLog(), "Initial", "Initial");
313 glu::Program program (m_context.getRenderContext());
314
315 verifyStateProgramInteger(result, gl, program.getProgram(), GL_ACTIVE_ATOMIC_COUNTER_BUFFERS, 0, m_verifier);
316 }
317
318 {
319 const tcu::ScopedLogSection section (m_testCtx.getLog(), "NoBuffers", "No buffers");
320 glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(s_computeSource0));
321
322 m_testCtx.getLog() << program;
323 if (!program.isOk())
324 throw tcu::TestError("failed to build program");
325
326 verifyStateProgramInteger(result, gl, program.getProgram(), GL_ACTIVE_ATOMIC_COUNTER_BUFFERS, 0, m_verifier);
327 }
328
329 {
330 const tcu::ScopedLogSection section (m_testCtx.getLog(), "OneBuffer", "One buffer");
331 glu::ShaderProgram program (m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(s_computeSource1));
332
333 m_testCtx.getLog() << program;
334 if (!program.isOk())
335 throw tcu::TestError("failed to build program");
336
337 verifyStateProgramInteger(result, gl, program.getProgram(), GL_ACTIVE_ATOMIC_COUNTER_BUFFERS, 1, m_verifier);
338 }
339
340 result.setTestContextResult(m_testCtx);
341 return STOP;
342 }
343
344 class ProgramLogCase : public TestCase
345 {
346 public:
347 enum BuildErrorType
348 {
349 BUILDERROR_VERTEX_FRAGMENT = 0,
350 BUILDERROR_COMPUTE,
351 BUILDERROR_GEOMETRY,
352 BUILDERROR_TESSELLATION,
353 };
354
355 ProgramLogCase (Context& ctx, const char* name, const char* desc, BuildErrorType errorType);
356
357 private:
358 void init (void);
359 IterateResult iterate (void);
360 glu::ProgramSources getProgramSources (void) const;
361
362 const BuildErrorType m_buildErrorType;
363 };
364
ProgramLogCase(Context & ctx,const char * name,const char * desc,BuildErrorType errorType)365 ProgramLogCase::ProgramLogCase (Context& ctx, const char* name, const char* desc, BuildErrorType errorType)
366 : TestCase (ctx, name, desc)
367 , m_buildErrorType (errorType)
368 {
369 }
370
init(void)371 void ProgramLogCase::init (void)
372 {
373 switch (m_buildErrorType)
374 {
375 case BUILDERROR_VERTEX_FRAGMENT:
376 case BUILDERROR_COMPUTE:
377 break;
378
379 case BUILDERROR_GEOMETRY:
380 if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
381 throw tcu::NotSupportedError("Test requires GL_EXT_geometry_shader extension");
382 break;
383
384 case BUILDERROR_TESSELLATION:
385 if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
386 throw tcu::NotSupportedError("Test requires GL_EXT_tessellation_shader extension");
387 break;
388
389 default:
390 DE_ASSERT(false);
391 break;
392 }
393 }
394
iterate(void)395 ProgramLogCase::IterateResult ProgramLogCase::iterate (void)
396 {
397 using gls::StateQueryUtil::StateQueryMemoryWriteGuard;
398
399 tcu::ResultCollector result (m_testCtx.getLog());
400 glu::CallLogWrapper gl (m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
401 glu::ShaderProgram program (m_context.getRenderContext(), getProgramSources());
402 StateQueryMemoryWriteGuard<glw::GLint> logLen;
403
404 gl.enableLogging(true);
405
406 m_testCtx.getLog() << tcu::TestLog::Message << "Trying to link a broken program." << tcu::TestLog::EndMessage;
407
408 gl.glGetProgramiv(program.getProgram(), GL_INFO_LOG_LENGTH, &logLen);
409 logLen.verifyValidity(result);
410
411 if (logLen.verifyValidity(result))
412 verifyInfoLogQuery(result, gl, logLen, program.getProgram(), &glu::CallLogWrapper::glGetProgramInfoLog, "glGetProgramInfoLog");
413
414 result.setTestContextResult(m_testCtx);
415 return STOP;
416 }
417
getProgramSources(void) const418 glu::ProgramSources ProgramLogCase::getProgramSources (void) const
419 {
420 switch (m_buildErrorType)
421 {
422 case BUILDERROR_VERTEX_FRAGMENT:
423 return glu::ProgramSources()
424 << glu::VertexSource("#version 310 es\n"
425 "in highp vec4 a_pos;\n"
426 "uniform highp vec4 u_uniform;\n"
427 "void main()\n"
428 "{\n"
429 " gl_Position = a_pos + u_uniform;\n"
430 "}\n")
431 << glu::FragmentSource("#version 310 es\n"
432 "in highp vec4 v_missingVar;\n"
433 "uniform highp int u_uniform;\n"
434 "layout(location = 0) out mediump vec4 fragColor;\n"
435 "void main()\n"
436 "{\n"
437 " fragColor = v_missingVar + vec4(float(u_uniform));\n"
438 "}\n");
439
440 case BUILDERROR_COMPUTE:
441 return glu::ProgramSources()
442 << glu::ComputeSource("#version 310 es\n"
443 "layout (binding = 0) buffer IOBuffer { highp float buf_var; };\n"
444 "uniform highp vec4 u_uniform;\n"
445 "void main()\n"
446 "{\n"
447 " buf_var = u_uniform.x;\n"
448 "}\n");
449
450 case BUILDERROR_GEOMETRY:
451 return glu::ProgramSources()
452 << glu::VertexSource("#version 310 es\n"
453 "in highp vec4 a_pos;\n"
454 "uniform highp vec4 u_uniform;\n"
455 "void main()\n"
456 "{\n"
457 " gl_Position = a_pos + u_uniform;\n"
458 "}\n")
459 << glu::GeometrySource("#version 310 es\n"
460 "#extension GL_EXT_geometry_shader : require\n"
461 "layout(triangles) in;\n"
462 "layout(max_vertices=1, points) out;\n"
463 "in highp vec4 v_missingVar[];\n"
464 "uniform highp int u_uniform;\n"
465 "void main()\n"
466 "{\n"
467 " gl_Position = gl_in[0].gl_Position + v_missingVar[2] + vec4(float(u_uniform));\n"
468 " EmitVertex();\n"
469 "}\n")
470 << glu::FragmentSource("#version 310 es\n"
471 "layout(location = 0) out mediump vec4 fragColor;\n"
472 "void main()\n"
473 "{\n"
474 " fragColor = vec4(1.0);\n"
475 "}\n");
476
477 case BUILDERROR_TESSELLATION:
478 return glu::ProgramSources()
479 << glu::VertexSource("#version 310 es\n"
480 "in highp vec4 a_pos;\n"
481 "void main()\n"
482 "{\n"
483 " gl_Position = a_pos;\n"
484 "}\n")
485 << glu::TessellationControlSource("#version 310 es\n"
486 "#extension GL_EXT_tessellation_shader : require\n"
487 "layout(vertices=2) out;"
488 "patch out highp vec2 vp_var;\n"
489 "void main()\n"
490 "{\n"
491 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position\n"
492 " gl_TessLevelOuter[0] = 0.8;\n"
493 " gl_TessLevelOuter[1] = 0.8;\n"
494 " if (gl_InvocationID == 0)\n"
495 " vp_var = gl_in[gl_InvocationID].gl_Position.xy;\n"
496 "}\n")
497 << glu::TessellationEvaluationSource("#version 310 es\n"
498 "#extension GL_EXT_tessellation_shader : require\n"
499 "layout(isolines) in;"
500 "in highp float vp_var[];\n"
501 "void main()\n"
502 "{\n"
503 " gl_Position = gl_in[gl_InvocationID].gl_Position + vec4(vp_var[1]);\n"
504 "}\n")
505 << glu::FragmentSource("#version 310 es\n"
506 "layout(location = 0) out mediump vec4 fragColor;\n"
507 "void main()\n"
508 "{\n"
509 " fragColor = vec4(1.0);\n"
510 "}\n");
511
512 default:
513 DE_ASSERT(false);
514 return glu::ProgramSources();
515 }
516 }
517
518 } // anonymous
519
ProgramStateQueryTests(Context & context)520 ProgramStateQueryTests::ProgramStateQueryTests (Context& context)
521 : TestCaseGroup(context, "program", "Program State Query tests")
522 {
523 }
524
~ProgramStateQueryTests(void)525 ProgramStateQueryTests::~ProgramStateQueryTests (void)
526 {
527 }
528
init(void)529 void ProgramStateQueryTests::init (void)
530 {
531 static const QueryType intVerifiers[] =
532 {
533 QUERY_PROGRAM_INTEGER,
534 };
535 static const QueryType intVec3Verifiers[] =
536 {
537 QUERY_PROGRAM_INTEGER_VEC3,
538 };
539
540 #define FOR_EACH_INT_VERIFIER(X) \
541 for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(intVerifiers); ++verifierNdx) \
542 { \
543 const char* verifierSuffix = getVerifierSuffix(intVerifiers[verifierNdx]); \
544 const QueryType verifier = intVerifiers[verifierNdx]; \
545 this->addChild(X); \
546 }
547
548 #define FOR_EACH_VEC_VERIFIER(X) \
549 for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(intVec3Verifiers); ++verifierNdx) \
550 { \
551 const char* verifierSuffix = getVerifierSuffix(intVec3Verifiers[verifierNdx]); \
552 const QueryType verifier = intVec3Verifiers[verifierNdx]; \
553 this->addChild(X); \
554 }
555
556 FOR_EACH_INT_VERIFIER(new ProgramSeparableCase (m_context, verifier, (std::string("program_separable_") + verifierSuffix).c_str(), "Test PROGRAM_SEPARABLE"));
557 FOR_EACH_VEC_VERIFIER(new ComputeWorkGroupSizeCase (m_context, verifier, (std::string("compute_work_group_size_") + verifierSuffix).c_str(), "Test COMPUTE_WORK_GROUP_SIZE"));
558 FOR_EACH_INT_VERIFIER(new ActiveAtomicCounterBuffersCase (m_context, verifier, (std::string("active_atomic_counter_buffers_") + verifierSuffix).c_str(), "Test ACTIVE_ATOMIC_COUNTER_BUFFERS"));
559
560 #undef FOR_EACH_INT_VERIFIER
561 #undef FOR_EACH_VEC_VERIFIER
562
563 // program info log tests
564 // \note, there exists similar tests in gles3 module. However, the gles31 could use a different
565 // shader compiler with different INFO_LOG bugs.
566 {
567 static const struct
568 {
569 const char* caseName;
570 ProgramLogCase::BuildErrorType caseType;
571 } shaderTypes[] =
572 {
573 { "info_log_vertex_fragment_link_fail", ProgramLogCase::BUILDERROR_VERTEX_FRAGMENT },
574 { "info_log_compute_link_fail", ProgramLogCase::BUILDERROR_COMPUTE },
575 { "info_log_geometry_link_fail", ProgramLogCase::BUILDERROR_GEOMETRY },
576 { "info_log_tessellation_link_fail", ProgramLogCase::BUILDERROR_TESSELLATION },
577 };
578
579 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(shaderTypes); ++ndx)
580 addChild(new ProgramLogCase(m_context, shaderTypes[ndx].caseName, "", shaderTypes[ndx].caseType));
581 }
582 }
583
584 } // Functional
585 } // gles31
586 } // deqp
587