Home | History | Annotate | Download | only in functional
      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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    418 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 
    520 ProgramStateQueryTests::ProgramStateQueryTests (Context& context)
    521 	: TestCaseGroup(context, "program", "Program State Query tests")
    522 {
    523 }
    524 
    525 ProgramStateQueryTests::~ProgramStateQueryTests (void)
    526 {
    527 }
    528 
    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