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 #include "tcuStringTemplate.hpp"
     35 
     36 namespace deqp
     37 {
     38 
     39 using std::string;
     40 using std::map;
     41 
     42 namespace gles31
     43 {
     44 namespace Functional
     45 {
     46 namespace
     47 {
     48 
     49 using namespace gls::StateQueryUtil;
     50 
     51 static const char* getVerifierSuffix (QueryType type)
     52 {
     53 	switch (type)
     54 	{
     55 		case QUERY_PROGRAM_INTEGER_VEC3:
     56 		case QUERY_PROGRAM_INTEGER:
     57 			return "get_programiv";
     58 
     59 		default:
     60 			DE_ASSERT(DE_FALSE);
     61 			return DE_NULL;
     62 	}
     63 }
     64 
     65 static std::string specializeShader(Context& context, const char* code)
     66 {
     67 	const glu::GLSLVersion				glslVersion			= glu::getContextTypeGLSLVersion(context.getRenderContext().getType());
     68 	std::map<std::string, std::string>	specializationMap;
     69 
     70 	specializationMap["GLSL_VERSION_DECL"] = glu::getGLSLVersionDeclaration(glslVersion);
     71 
     72 	if (glu::contextSupports(context.getRenderContext().getType(), glu::ApiType::es(3, 2)))
     73 	{
     74 		specializationMap["GEOMETRY_SHADER_REQUIRE"] = "";
     75 		specializationMap["TESSELLATION_SHADER_REQUIRE"] = "";
     76 	}
     77 	else
     78 	{
     79 		specializationMap["GEOMETRY_SHADER_REQUIRE"] = "#extension GL_EXT_geometry_shader : require";
     80 		specializationMap["TESSELLATION_SHADER_REQUIRE"] = "#extension GL_EXT_tessellation_shader : require";
     81 	}
     82 
     83 	return tcu::StringTemplate(code).specialize(specializationMap);
     84 }
     85 
     86 
     87 class GeometryShaderCase : public TestCase
     88 {
     89 public:
     90 						GeometryShaderCase		(Context& context, QueryType verifier, const char* name, const char* desc);
     91 	IterateResult		iterate					(void);
     92 
     93 private:
     94 	const QueryType		m_verifier;
     95 };
     96 
     97 GeometryShaderCase::GeometryShaderCase (Context& context, QueryType verifier, const char* name, const char* desc)
     98 	: TestCase		(context, name, desc)
     99 	, m_verifier	(verifier)
    100 {
    101 }
    102 
    103 GeometryShaderCase::IterateResult GeometryShaderCase::iterate (void)
    104 {
    105 	const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
    106 
    107 	if (!supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
    108 		TCU_THROW(NotSupportedError, "Geometry shader tests require GL_EXT_geometry_shader extension or an OpenGL ES 3.2 or higher context.");
    109 
    110 
    111 	static const char* const	s_vtxFragTemplate	=	"${GLSL_VERSION_DECL}\n"
    112 														"void main()\n"
    113 														"{\n"
    114 														"}\n";
    115 
    116 	static const char* const	s_geometryTemplate1	=	"${GLSL_VERSION_DECL}\n"
    117 														"${GEOMETRY_SHADER_REQUIRE}\n"
    118 														"layout(triangles) in;"
    119 														"layout(triangle_strip, max_vertices = 3) out;\n"
    120 														"void main()\n"
    121 														"{\n"
    122 														"   EndPrimitive();\n"
    123 														"}\n";
    124 
    125 	static const char* const	s_geometryTemplate2	=	"${GLSL_VERSION_DECL}\n"
    126 														"${GEOMETRY_SHADER_REQUIRE}\n"
    127 														"layout(points) in;"
    128 														"layout(line_strip, max_vertices = 5) out;\n"
    129 														"void main()\n"
    130 														"{\n"
    131 														"   EndPrimitive();\n"
    132 														"}\n";
    133 
    134 	static const char* const	s_geometryTemplate3	=	"${GLSL_VERSION_DECL}\n"
    135 														"${GEOMETRY_SHADER_REQUIRE}\n"
    136 														"layout(points) in;"
    137 														"layout(points, max_vertices = 50) out;\n"
    138 														"void main()\n"
    139 														"{\n"
    140 														"   EndPrimitive();\n"
    141 														"}\n";
    142 
    143 	glu::CallLogWrapper			gl						(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
    144 	tcu::ResultCollector		result					(m_testCtx.getLog(), " // ERROR: ");
    145 
    146 	gl.enableLogging(true);
    147 
    148 	{
    149 		const tcu::ScopedLogSection	section		(m_testCtx.getLog(), "Layout", "triangles in, triangle strip out, 3 vertices");
    150 		glu::ShaderProgram			program		(m_context.getRenderContext(), glu::ProgramSources()
    151 			<< glu::VertexSource(specializeShader(m_context, s_vtxFragTemplate))
    152 			<< glu::FragmentSource(specializeShader(m_context, s_vtxFragTemplate))
    153 			<< glu::GeometrySource(specializeShader(m_context, s_geometryTemplate1)));
    154 
    155 		TCU_CHECK_MSG(program.isOk(), "Compile failed");
    156 
    157 		m_testCtx.getLog() << program;
    158 
    159 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_VERTICES_OUT, 3, m_verifier);
    160 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_INPUT_TYPE, GL_TRIANGLES, m_verifier);
    161 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_OUTPUT_TYPE, GL_TRIANGLE_STRIP, m_verifier);
    162 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_SHADER_INVOCATIONS, 1, m_verifier);
    163 	}
    164 
    165 	{
    166 		const tcu::ScopedLogSection	section		(m_testCtx.getLog(), "Layout", "points in, line strip out, 5 vertices");
    167 		glu::ShaderProgram			program		(m_context.getRenderContext(), glu::ProgramSources()
    168 			<< glu::VertexSource(specializeShader(m_context, s_vtxFragTemplate))
    169 			<< glu::FragmentSource(specializeShader(m_context, s_vtxFragTemplate))
    170 			<< glu::GeometrySource(specializeShader(m_context, s_geometryTemplate2)));
    171 
    172 		TCU_CHECK_MSG(program.isOk(), "Compile failed");
    173 
    174 		m_testCtx.getLog() << program;
    175 
    176 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_VERTICES_OUT, 5, m_verifier);
    177 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_INPUT_TYPE, GL_POINTS, m_verifier);
    178 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_OUTPUT_TYPE, GL_LINE_STRIP, m_verifier);
    179 	}
    180 
    181 	{
    182 		const tcu::ScopedLogSection	section		(m_testCtx.getLog(), "Layout", "points in, points out, 50 vertices");
    183 		glu::ShaderProgram			program		(m_context.getRenderContext(), glu::ProgramSources()
    184 			<< glu::VertexSource(specializeShader(m_context, s_vtxFragTemplate))
    185 			<< glu::FragmentSource(specializeShader(m_context, s_vtxFragTemplate))
    186 			<< glu::GeometrySource(specializeShader(m_context, s_geometryTemplate3)));
    187 
    188 		TCU_CHECK_MSG(program.isOk(), "Compile failed");
    189 
    190 		m_testCtx.getLog() << program;
    191 
    192 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_VERTICES_OUT, 50, m_verifier);
    193 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_INPUT_TYPE, GL_POINTS, m_verifier);
    194 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_GEOMETRY_OUTPUT_TYPE, GL_POINTS, m_verifier);
    195 	}
    196 
    197 	result.setTestContextResult(m_testCtx);
    198 	return STOP;
    199 }
    200 
    201 class TessellationShaderCase : public TestCase
    202 {
    203 public:
    204 						TessellationShaderCase		(Context& context, QueryType verifier, const char* name, const char* desc);
    205 	IterateResult		iterate					(void);
    206 
    207 private:
    208 	const QueryType		m_verifier;
    209 };
    210 
    211 TessellationShaderCase::TessellationShaderCase (Context& context, QueryType verifier, const char* name, const char* desc)
    212 	: TestCase		(context, name, desc)
    213 	, m_verifier	(verifier)
    214 {
    215 }
    216 
    217 TessellationShaderCase::IterateResult TessellationShaderCase::iterate (void)
    218 {
    219 	const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
    220 
    221 	if (!supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
    222 		TCU_THROW(NotSupportedError, "Tessellation shader tests require GL_EXT_tessellation_shader extension or an OpenGL ES 3.2 or higher context.");
    223 
    224 
    225 	static const char* const	s_vtxFragTemplate	=	"${GLSL_VERSION_DECL}\n"
    226 														"void main()\n"
    227 														"{\n"
    228 														"}\n";
    229 
    230 	static const char* const	s_tessCtrlTemplate1	=	"${GLSL_VERSION_DECL}\n"
    231 														"${TESSELLATION_SHADER_REQUIRE}\n"
    232 														"layout(vertices = 3) out;\n"
    233 														"void main()\n"
    234 														"{\n"
    235 														"}\n";
    236 
    237 	static const char* const	s_tessEvalTemplate1	=	"${GLSL_VERSION_DECL}\n"
    238 														"${TESSELLATION_SHADER_REQUIRE}\n"
    239 														"layout(triangles, equal_spacing, cw) in;\n"
    240 														"void main()\n"
    241 														"{\n"
    242 														"}\n";
    243 
    244 	static const char* const	s_tessCtrlTemplate2	=	"${GLSL_VERSION_DECL}\n"
    245 														"${TESSELLATION_SHADER_REQUIRE}\n"
    246 														"layout(vertices = 5) out;\n"
    247 														"void main()\n"
    248 														"{\n"
    249 														"}\n";
    250 
    251 	static const char* const	s_tessEvalTemplate2	=	"${GLSL_VERSION_DECL}\n"
    252 														"${TESSELLATION_SHADER_REQUIRE}\n"
    253 														"layout(quads, fractional_even_spacing, ccw) in;\n"
    254 														"void main()\n"
    255 														"{\n"
    256 														"}\n";
    257 
    258 	static const char* const	s_tessEvalTemplate3	=	"${GLSL_VERSION_DECL}\n"
    259 														"${TESSELLATION_SHADER_REQUIRE}\n"
    260 														"layout(isolines, fractional_odd_spacing, ccw, point_mode) in;\n"
    261 														"void main()\n"
    262 														"{\n"
    263 														"}\n";
    264 
    265 	glu::CallLogWrapper			gl						(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
    266 	tcu::ResultCollector		result					(m_testCtx.getLog(), " // ERROR: ");
    267 
    268 	gl.enableLogging(true);
    269 
    270 	{
    271 		const tcu::ScopedLogSection	section		(m_testCtx.getLog(), "Query State", "3 vertices, triangles, equal_spacing, cw");
    272 		glu::ShaderProgram			program		(m_context.getRenderContext(), glu::ProgramSources()
    273 			<< glu::VertexSource(specializeShader(m_context, s_vtxFragTemplate))
    274 			<< glu::FragmentSource(specializeShader(m_context, s_vtxFragTemplate))
    275 			<< glu::TessellationControlSource(specializeShader(m_context, s_tessCtrlTemplate1))
    276 			<< glu::TessellationEvaluationSource(specializeShader(m_context, s_tessEvalTemplate1)));
    277 
    278 		TCU_CHECK_MSG(program.isOk(), "Compile failed");
    279 
    280 		m_testCtx.getLog() << program;
    281 
    282 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_CONTROL_OUTPUT_VERTICES, 3, m_verifier);
    283 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_MODE, GL_TRIANGLES, m_verifier);
    284 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_SPACING, GL_EQUAL, m_verifier);
    285 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_VERTEX_ORDER, GL_CW, m_verifier);
    286 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_POINT_MODE, GL_FALSE, m_verifier);
    287 	}
    288 
    289 	{
    290 		const tcu::ScopedLogSection	section		(m_testCtx.getLog(), "Query State", "5 vertices, quads, fractional_even_spacing, ccw");
    291 		glu::ShaderProgram			program		(m_context.getRenderContext(), glu::ProgramSources()
    292 			<< glu::VertexSource(specializeShader(m_context, s_vtxFragTemplate))
    293 			<< glu::FragmentSource(specializeShader(m_context, s_vtxFragTemplate))
    294 			<< glu::TessellationControlSource(specializeShader(m_context, s_tessCtrlTemplate2))
    295 			<< glu::TessellationEvaluationSource(specializeShader(m_context, s_tessEvalTemplate2)));
    296 
    297 		TCU_CHECK_MSG(program.isOk(), "Compile failed");
    298 
    299 		m_testCtx.getLog() << program;
    300 
    301 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_CONTROL_OUTPUT_VERTICES, 5, m_verifier);
    302 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_MODE, GL_QUADS, m_verifier);
    303 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_SPACING, GL_FRACTIONAL_EVEN, m_verifier);
    304 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_VERTEX_ORDER, GL_CCW, m_verifier);
    305 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_POINT_MODE, GL_FALSE, m_verifier);
    306 	}
    307 
    308 	{
    309 		const tcu::ScopedLogSection	section		(m_testCtx.getLog(), "Query State", "5 vertices, isolines, fractional_odd_spacing, ccw, point_mode");
    310 		glu::ShaderProgram			program		(m_context.getRenderContext(), glu::ProgramSources()
    311 			<< glu::VertexSource(specializeShader(m_context, s_vtxFragTemplate))
    312 			<< glu::FragmentSource(specializeShader(m_context, s_vtxFragTemplate))
    313 			<< glu::TessellationControlSource(specializeShader(m_context, s_tessCtrlTemplate2))
    314 			<< glu::TessellationEvaluationSource(specializeShader(m_context, s_tessEvalTemplate3)));
    315 
    316 		TCU_CHECK_MSG(program.isOk(), "Compile failed");
    317 
    318 		m_testCtx.getLog() << program;
    319 
    320 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_CONTROL_OUTPUT_VERTICES, 5, m_verifier);
    321 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_MODE, GL_ISOLINES, m_verifier);
    322 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_SPACING, GL_FRACTIONAL_ODD, m_verifier);
    323 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_VERTEX_ORDER, GL_CCW, m_verifier);
    324 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_TESS_GEN_POINT_MODE, GL_TRUE, m_verifier);
    325 	}
    326 
    327 	result.setTestContextResult(m_testCtx);
    328 	return STOP;
    329 }
    330 
    331 class ProgramSeparableCase : public TestCase
    332 {
    333 public:
    334 						ProgramSeparableCase	(Context& context, QueryType verifier, const char* name, const char* desc);
    335 	IterateResult		iterate					(void);
    336 
    337 private:
    338 	const QueryType		m_verifier;
    339 };
    340 
    341 ProgramSeparableCase::ProgramSeparableCase (Context& context, QueryType verifier, const char* name, const char* desc)
    342 	: TestCase		(context, name, desc)
    343 	, m_verifier	(verifier)
    344 {
    345 }
    346 
    347 ProgramSeparableCase::IterateResult ProgramSeparableCase::iterate (void)
    348 {
    349 	const string				vtxTemplate	=	"${GLSL_VERSION_DECL}\n"
    350 												"out highp vec4 v_color;\n"
    351 												"void main()\n"
    352 												"{\n"
    353 												"	gl_Position = vec4(float(gl_VertexID) * 0.5, float(gl_VertexID+1) * 0.5, 0.0, 1.0);\n"
    354 												"	v_color = vec4(float(gl_VertexID), 1.0, 0.0, 1.0);\n"
    355 												"}\n";
    356 	const string				fragTemplate =	"${GLSL_VERSION_DECL}\n"
    357 												"in highp vec4 v_color;\n"
    358 												"layout(location=0) out highp vec4 o_color;\n"
    359 												"void main()\n"
    360 												"{\n"
    361 												"	o_color = v_color;\n"
    362 												"}\n";
    363 
    364 	glu::CallLogWrapper			gl				(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
    365 	tcu::ResultCollector		result			(m_testCtx.getLog(), " // ERROR: ");
    366 	glu::Shader					vtxShader		(m_context.getRenderContext(), glu::SHADERTYPE_VERTEX);
    367 	glu::Shader					frgShader		(m_context.getRenderContext(), glu::SHADERTYPE_FRAGMENT);
    368 
    369 	const std::string			vStr			= specializeShader(m_context, vtxTemplate.c_str());
    370 	const std::string			fStr			= specializeShader(m_context, fragTemplate.c_str());
    371 	const char* const			vtxSourcePtr	= vStr.c_str();
    372 	const char* const			fragSourcePtr	= fStr.c_str();
    373 
    374 	vtxShader.setSources(1, &vtxSourcePtr, DE_NULL);
    375 	frgShader.setSources(1, &fragSourcePtr, DE_NULL);
    376 
    377 	vtxShader.compile();
    378 	frgShader.compile();
    379 
    380 	{
    381 		const tcu::ScopedLogSection section(m_testCtx.getLog(), "VtxShader", "Vertex shader");
    382 		m_testCtx.getLog() << vtxShader;
    383 	}
    384 
    385 	{
    386 		const tcu::ScopedLogSection section(m_testCtx.getLog(), "FrgShader", "Fragment shader");
    387 		m_testCtx.getLog() << frgShader;
    388 	}
    389 
    390 	TCU_CHECK_MSG(vtxShader.getCompileStatus() && frgShader.getCompileStatus(), "failed to build shaders");
    391 
    392 	gl.enableLogging(true);
    393 
    394 	{
    395 		const tcu::ScopedLogSection	section	(m_testCtx.getLog(), "Initial", "Initial");
    396 		glu::Program				program	(m_context.getRenderContext());
    397 
    398 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_PROGRAM_SEPARABLE, 0, m_verifier);
    399 	}
    400 
    401 	{
    402 		const tcu::ScopedLogSection section		(m_testCtx.getLog(), "SetFalse", "SetFalse");
    403 		glu::Program				program		(m_context.getRenderContext());
    404 		int							linkStatus	= 0;
    405 
    406 		gl.glAttachShader(program.getProgram(), vtxShader.getShader());
    407 		gl.glAttachShader(program.getProgram(), frgShader.getShader());
    408 		gl.glProgramParameteri(program.getProgram(), GL_PROGRAM_SEPARABLE, GL_FALSE);
    409 		gl.glLinkProgram(program.getProgram());
    410 		GLU_EXPECT_NO_ERROR(gl.glGetError(), "setup program");
    411 
    412 		gl.glGetProgramiv(program.getProgram(), GL_LINK_STATUS, &linkStatus);
    413 		GLU_EXPECT_NO_ERROR(gl.glGetError(), "query link status");
    414 
    415 		TCU_CHECK_MSG(linkStatus == GL_TRUE, "failed to link program");
    416 
    417 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_PROGRAM_SEPARABLE, 0, m_verifier);
    418 	}
    419 
    420 	{
    421 		const tcu::ScopedLogSection section		(m_testCtx.getLog(), "SetTrue", "SetTrue");
    422 		glu::Program				program		(m_context.getRenderContext());
    423 		int							linkStatus	= 0;
    424 
    425 		gl.glAttachShader(program.getProgram(), vtxShader.getShader());
    426 		gl.glAttachShader(program.getProgram(), frgShader.getShader());
    427 		gl.glProgramParameteri(program.getProgram(), GL_PROGRAM_SEPARABLE, GL_TRUE);
    428 		gl.glLinkProgram(program.getProgram());
    429 		GLU_EXPECT_NO_ERROR(gl.glGetError(), "setup program");
    430 
    431 		gl.glGetProgramiv(program.getProgram(), GL_LINK_STATUS, &linkStatus);
    432 		GLU_EXPECT_NO_ERROR(gl.glGetError(), "query link status");
    433 
    434 		TCU_CHECK_MSG(linkStatus == GL_TRUE, "failed to link program");
    435 
    436 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_PROGRAM_SEPARABLE, GL_TRUE, m_verifier);
    437 	}
    438 
    439 	result.setTestContextResult(m_testCtx);
    440 	return STOP;
    441 }
    442 
    443 class ComputeWorkGroupSizeCase : public TestCase
    444 {
    445 public:
    446 						ComputeWorkGroupSizeCase	(Context& context, QueryType verifier, const char* name, const char* desc);
    447 	IterateResult		iterate						(void);
    448 
    449 private:
    450 	const QueryType		m_verifier;
    451 };
    452 
    453 ComputeWorkGroupSizeCase::ComputeWorkGroupSizeCase (Context& context, QueryType verifier, const char* name, const char* desc)
    454 	: TestCase		(context, name, desc)
    455 	, m_verifier	(verifier)
    456 {
    457 }
    458 
    459 ComputeWorkGroupSizeCase::IterateResult ComputeWorkGroupSizeCase::iterate (void)
    460 {
    461 	static const char* const	s_computeTemplate1D =	"${GLSL_VERSION_DECL}\n"
    462 														"layout (local_size_x = 3) in;\n"
    463 														"layout(binding = 0) buffer Output\n"
    464 														"{\n"
    465 														"	highp float val;\n"
    466 														"} sb_out;\n"
    467 														"\n"
    468 														"void main (void)\n"
    469 														"{\n"
    470 														"	sb_out.val = 1.0;\n"
    471 														"}\n";
    472 	static const char* const	s_computeTemplate2D =	"${GLSL_VERSION_DECL}\n"
    473 														"layout (local_size_x = 3, local_size_y = 2) in;\n"
    474 														"layout(binding = 0) buffer Output\n"
    475 														"{\n"
    476 														"	highp float val;\n"
    477 														"} sb_out;\n"
    478 														"\n"
    479 														"void main (void)\n"
    480 														"{\n"
    481 														"	sb_out.val = 1.0;\n"
    482 														"}\n";
    483 	static const char* const	s_computeTemplate3D =	"${GLSL_VERSION_DECL}\n"
    484 														"layout (local_size_x = 3, local_size_y = 2, local_size_z = 4) in;\n"
    485 														"layout(binding = 0) buffer Output\n"
    486 														"{\n"
    487 														"	highp float val;\n"
    488 														"} sb_out;\n"
    489 														"\n"
    490 														"void main (void)\n"
    491 														"{\n"
    492 														"	sb_out.val = 1.0;\n"
    493 														"}\n";
    494 
    495 	glu::CallLogWrapper			gl						(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
    496 	tcu::ResultCollector		result					(m_testCtx.getLog(), " // ERROR: ");
    497 
    498 	gl.enableLogging(true);
    499 
    500 	{
    501 		const tcu::ScopedLogSection section		(m_testCtx.getLog(), "OneDimensional", "1D");
    502 		glu::ShaderProgram			program		(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(specializeShader(m_context, s_computeTemplate1D)));
    503 
    504 		m_testCtx.getLog() << program;
    505 
    506 		TCU_CHECK_MSG(program.isOk(), "failed to build program");
    507 
    508 		verifyStateProgramIntegerVec3(result, gl, program.getProgram(), GL_COMPUTE_WORK_GROUP_SIZE, tcu::IVec3(3, 1, 1), m_verifier);
    509 	}
    510 
    511 	{
    512 		const tcu::ScopedLogSection section		(m_testCtx.getLog(), "TwoDimensional", "2D");
    513 		glu::ShaderProgram			program		(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(specializeShader(m_context, s_computeTemplate2D)));
    514 
    515 		m_testCtx.getLog() << program;
    516 
    517 		TCU_CHECK_MSG(program.isOk(), "failed to build program");
    518 
    519 		verifyStateProgramIntegerVec3(result, gl, program.getProgram(), GL_COMPUTE_WORK_GROUP_SIZE, tcu::IVec3(3, 2, 1), m_verifier);
    520 	}
    521 
    522 	{
    523 		const tcu::ScopedLogSection section		(m_testCtx.getLog(), "TreeDimensional", "3D");
    524 		glu::ShaderProgram			program		(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(specializeShader(m_context, s_computeTemplate3D)));
    525 
    526 		m_testCtx.getLog() << program;
    527 
    528 		TCU_CHECK_MSG(program.isOk(), "failed to build program");
    529 
    530 		verifyStateProgramIntegerVec3(result, gl, program.getProgram(), GL_COMPUTE_WORK_GROUP_SIZE, tcu::IVec3(3, 2, 4), m_verifier);
    531 	}
    532 
    533 	result.setTestContextResult(m_testCtx);
    534 	return STOP;
    535 }
    536 
    537 class ActiveAtomicCounterBuffersCase : public TestCase
    538 {
    539 public:
    540 						ActiveAtomicCounterBuffersCase	(Context& context, QueryType verifier, const char* name, const char* desc);
    541 	IterateResult		iterate							(void);
    542 
    543 private:
    544 	const QueryType		m_verifier;
    545 };
    546 
    547 ActiveAtomicCounterBuffersCase::ActiveAtomicCounterBuffersCase (Context& context, QueryType verifier, const char* name, const char* desc)
    548 	: TestCase		(context, name, desc)
    549 	, m_verifier	(verifier)
    550 {
    551 }
    552 
    553 ActiveAtomicCounterBuffersCase::IterateResult ActiveAtomicCounterBuffersCase::iterate (void)
    554 {
    555 	static const char* const	s_computeTemplate0	=	"${GLSL_VERSION_DECL}\n"
    556 														"layout (local_size_x = 3) in;\n"
    557 														"layout(binding = 0) buffer Output\n"
    558 														"{\n"
    559 														"	highp float val;\n"
    560 														"} sb_out;\n"
    561 														"\n"
    562 														"void main (void)\n"
    563 														"{\n"
    564 														"	sb_out.val = 1.0;\n"
    565 														"}\n";
    566 	static const char* const	s_computeTemplate1	=	"${GLSL_VERSION_DECL}\n"
    567 														"layout (local_size_x = 3) in;\n"
    568 														"layout(binding = 0) uniform highp atomic_uint u_counters[2];\n"
    569 														"layout(binding = 0) buffer Output\n"
    570 														"{\n"
    571 														"	highp float val;\n"
    572 														"} sb_out;\n"
    573 														"\n"
    574 														"void main (void)\n"
    575 														"{\n"
    576 														"	sb_out.val = float(atomicCounterIncrement(u_counters[0])) + float(atomicCounterIncrement(u_counters[1]));\n"
    577 														"}\n";
    578 
    579 	glu::CallLogWrapper			gl						(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
    580 	tcu::ResultCollector		result					(m_testCtx.getLog(), " // ERROR: ");
    581 
    582 	gl.enableLogging(true);
    583 
    584 	{
    585 		const tcu::ScopedLogSection	section		(m_testCtx.getLog(), "Initial", "Initial");
    586 		glu::Program				program		(m_context.getRenderContext());
    587 
    588 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_ACTIVE_ATOMIC_COUNTER_BUFFERS, 0, m_verifier);
    589 	}
    590 
    591 	{
    592 		const tcu::ScopedLogSection	section		(m_testCtx.getLog(), "NoBuffers", "No buffers");
    593 		glu::ShaderProgram			program		(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(specializeShader(m_context, s_computeTemplate0)));
    594 
    595 		m_testCtx.getLog() << program;
    596 
    597 		TCU_CHECK_MSG(program.isOk(), "failed to build program");
    598 
    599 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_ACTIVE_ATOMIC_COUNTER_BUFFERS, 0, m_verifier);
    600 	}
    601 
    602 	{
    603 		const tcu::ScopedLogSection	section		(m_testCtx.getLog(), "OneBuffer", "One buffer");
    604 		glu::ShaderProgram			program		(m_context.getRenderContext(), glu::ProgramSources() << glu::ComputeSource(specializeShader(m_context, s_computeTemplate1)));
    605 
    606 		m_testCtx.getLog() << program;
    607 
    608 		TCU_CHECK_MSG(program.isOk(), "failed to build program");
    609 
    610 		verifyStateProgramInteger(result, gl, program.getProgram(), GL_ACTIVE_ATOMIC_COUNTER_BUFFERS, 1, m_verifier);
    611 	}
    612 
    613 	result.setTestContextResult(m_testCtx);
    614 	return STOP;
    615 }
    616 
    617 class ProgramLogCase : public TestCase
    618 {
    619 public:
    620 	enum BuildErrorType
    621 	{
    622 		BUILDERROR_VERTEX_FRAGMENT = 0,
    623 		BUILDERROR_COMPUTE,
    624 		BUILDERROR_GEOMETRY,
    625 		BUILDERROR_TESSELLATION,
    626 	};
    627 
    628 							ProgramLogCase		(Context& ctx, const char* name, const char* desc, BuildErrorType errorType);
    629 
    630 private:
    631 	void					init				(void);
    632 	IterateResult			iterate				(void);
    633 	glu::ProgramSources		getProgramSources	(void) const;
    634 
    635 	const BuildErrorType	m_buildErrorType;
    636 };
    637 
    638 ProgramLogCase::ProgramLogCase (Context& ctx, const char* name, const char* desc, BuildErrorType errorType)
    639 	: TestCase			(ctx, name, desc)
    640 	, m_buildErrorType	(errorType)
    641 {
    642 }
    643 
    644 void ProgramLogCase::init (void)
    645 {
    646 	const bool supportsES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
    647 
    648 	switch (m_buildErrorType)
    649 	{
    650 		case BUILDERROR_VERTEX_FRAGMENT:
    651 		case BUILDERROR_COMPUTE:
    652 			break;
    653 
    654 		case BUILDERROR_GEOMETRY:
    655 			if (!supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"))
    656 				TCU_THROW(NotSupportedError, "Test requires GL_EXT_geometry_shader extension");
    657 			break;
    658 
    659 		case BUILDERROR_TESSELLATION:
    660 			if (!supportsES32 && !m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"))
    661 				TCU_THROW(NotSupportedError, "Test requires GL_EXT_tessellation_shader extension");
    662 			break;
    663 
    664 		default:
    665 			DE_ASSERT(false);
    666 			break;
    667 	}
    668 }
    669 
    670 ProgramLogCase::IterateResult ProgramLogCase::iterate (void)
    671 {
    672 	using gls::StateQueryUtil::StateQueryMemoryWriteGuard;
    673 
    674 	tcu::ResultCollector					result		(m_testCtx.getLog());
    675 	glu::CallLogWrapper						gl			(m_context.getRenderContext().getFunctions(), m_testCtx.getLog());
    676 	glu::ShaderProgram						program		(m_context.getRenderContext(), getProgramSources());
    677 	StateQueryMemoryWriteGuard<glw::GLint>	logLen;
    678 
    679 	gl.enableLogging(true);
    680 
    681 	m_testCtx.getLog() << tcu::TestLog::Message << "Trying to link a broken program." << tcu::TestLog::EndMessage;
    682 
    683 	gl.glGetProgramiv(program.getProgram(), GL_INFO_LOG_LENGTH, &logLen);
    684 	logLen.verifyValidity(result);
    685 
    686 	if (logLen.verifyValidity(result))
    687 		verifyInfoLogQuery(result, gl, logLen, program.getProgram(), &glu::CallLogWrapper::glGetProgramInfoLog, "glGetProgramInfoLog");
    688 
    689 	result.setTestContextResult(m_testCtx);
    690 	return STOP;
    691 }
    692 
    693 glu::ProgramSources ProgramLogCase::getProgramSources (void) const
    694 {
    695 	const char* const	vertexTemplate1 =	"${GLSL_VERSION_DECL}\n"
    696 											"in highp vec4 a_pos;\n"
    697 											"uniform highp vec4 u_uniform;\n"
    698 											"void main()\n"
    699 											"{\n"
    700 											"	gl_Position = a_pos + u_uniform;\n"
    701 											"}\n";
    702 	const char* const	vertexTemplate2 =	"${GLSL_VERSION_DECL}\n"
    703 											"in highp vec4 a_pos;\n"
    704 											"void main()\n"
    705 											"{\n"
    706 											"	gl_Position = a_pos;\n"
    707 											"}\n";
    708 	const char* const	fragmentTemplate1 =	"${GLSL_VERSION_DECL}\n"
    709 											"in highp vec4 v_missingVar;\n"
    710 											"uniform highp int u_uniform;\n"
    711 											"layout(location = 0) out mediump vec4 fragColor;\n"
    712 											"void main()\n"
    713 											"{\n"
    714 											"	fragColor = v_missingVar + vec4(float(u_uniform));\n"
    715 											"}\n";
    716 
    717 	const char* const	fragmentTemplate2 =	"${GLSL_VERSION_DECL}\n"
    718 											"layout(location = 0) out mediump vec4 fragColor;\n"
    719 											"void main()\n"
    720 											"{\n"
    721 											"	fragColor = vec4(1.0);\n"
    722 											"}\n";
    723 	const char* const	computeTemplate1 =	"${GLSL_VERSION_DECL}\n"
    724 											"layout (binding = 0) buffer IOBuffer { highp float buf_var; };\n"
    725 											"uniform highp vec4 u_uniform;\n"
    726 											"void main()\n"
    727 											"{\n"
    728 											"	buf_var = u_uniform.x;\n"
    729 											"}\n";
    730 	const char* const	geometryTemplate1 =	"${GLSL_VERSION_DECL}\n"
    731 											"${GEOMETRY_SHADER_REQUIRE}\n"
    732 											"layout(triangles) in;\n"
    733 											"layout(max_vertices=1, points) out;\n"
    734 											"in highp vec4 v_missingVar[];\n"
    735 											"uniform highp int u_uniform;\n"
    736 											"void main()\n"
    737 											"{\n"
    738 											"	gl_Position = gl_in[0].gl_Position + v_missingVar[2] + vec4(float(u_uniform));\n"
    739 											"	EmitVertex();\n"
    740 											"}\n";
    741 	const char* const	tessCtrlTemplate1 =	"${GLSL_VERSION_DECL}\n"
    742 											"${TESSELLATION_SHADER_REQUIRE}\n"
    743 											"layout(vertices=2) out;"
    744 											"patch out highp vec2 vp_var;\n"
    745 											"void main()\n"
    746 											"{\n"
    747 											"	gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position\n"
    748 											"	gl_TessLevelOuter[0] = 0.8;\n"
    749 											"	gl_TessLevelOuter[1] = 0.8;\n"
    750 											"	if (gl_InvocationID == 0)\n"
    751 											"		vp_var = gl_in[gl_InvocationID].gl_Position.xy;\n"
    752 											"}\n";
    753 	const char* const	tessEvalTemplate1 =	"${GLSL_VERSION_DECL}\n"
    754 											"${TESSELLATION_SHADER_REQUIRE}\n"
    755 											"layout(isolines) in;"
    756 											"in highp float vp_var[];\n"
    757 											"void main()\n"
    758 											"{\n"
    759 											"	gl_Position = gl_in[gl_InvocationID].gl_Position + vec4(vp_var[1]);\n"
    760 											"}\n";
    761 
    762 	switch (m_buildErrorType)
    763 	{
    764 		case BUILDERROR_VERTEX_FRAGMENT:
    765 			return glu::ProgramSources()
    766 					<< glu::VertexSource(specializeShader(m_context, vertexTemplate1))
    767 					<< glu::FragmentSource(specializeShader(m_context, fragmentTemplate1));
    768 
    769 		case BUILDERROR_COMPUTE:
    770 			return glu::ProgramSources()
    771 					<< glu::ComputeSource(specializeShader(m_context, computeTemplate1));
    772 
    773 		case BUILDERROR_GEOMETRY:
    774 			return glu::ProgramSources()
    775 					<< glu::VertexSource(specializeShader(m_context, vertexTemplate1))
    776 					<< glu::GeometrySource(specializeShader(m_context, geometryTemplate1))
    777 					<< glu::FragmentSource(specializeShader(m_context, fragmentTemplate2));
    778 
    779 		case BUILDERROR_TESSELLATION:
    780 			return glu::ProgramSources()
    781 					<< glu::VertexSource(specializeShader(m_context, vertexTemplate2))
    782 					<< glu::TessellationControlSource(specializeShader(m_context, tessCtrlTemplate1))
    783 					<< glu::TessellationEvaluationSource(specializeShader(m_context, tessEvalTemplate1))
    784 					<< glu::FragmentSource(specializeShader(m_context, fragmentTemplate2));
    785 
    786 		default:
    787 			DE_ASSERT(false);
    788 			return glu::ProgramSources();
    789 	}
    790 }
    791 
    792 } // anonymous
    793 
    794 ProgramStateQueryTests::ProgramStateQueryTests (Context& context)
    795 	: TestCaseGroup(context, "program", "Program State Query tests")
    796 {
    797 }
    798 
    799 ProgramStateQueryTests::~ProgramStateQueryTests (void)
    800 {
    801 }
    802 
    803 void ProgramStateQueryTests::init (void)
    804 {
    805 	static const QueryType intVerifiers[] =
    806 	{
    807 		QUERY_PROGRAM_INTEGER,
    808 	};
    809 	static const QueryType intVec3Verifiers[] =
    810 	{
    811 		QUERY_PROGRAM_INTEGER_VEC3,
    812 	};
    813 
    814 #define FOR_EACH_INT_VERIFIER(X) \
    815 	for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(intVerifiers); ++verifierNdx)	\
    816 	{																							\
    817 		const char* verifierSuffix = getVerifierSuffix(intVerifiers[verifierNdx]);				\
    818 		const QueryType verifier = intVerifiers[verifierNdx];									\
    819 		this->addChild(X);																		\
    820 	}
    821 
    822 #define FOR_EACH_VEC_VERIFIER(X) \
    823 	for (int verifierNdx = 0; verifierNdx < DE_LENGTH_OF_ARRAY(intVec3Verifiers); ++verifierNdx)	\
    824 	{																								\
    825 		const char* verifierSuffix = getVerifierSuffix(intVec3Verifiers[verifierNdx]);				\
    826 		const QueryType verifier = intVec3Verifiers[verifierNdx];									\
    827 		this->addChild(X);																			\
    828 	}
    829 
    830 	FOR_EACH_INT_VERIFIER(new ProgramSeparableCase				(m_context, verifier, (std::string("program_separable_") + verifierSuffix).c_str(),				"Test PROGRAM_SEPARABLE"));
    831 	FOR_EACH_VEC_VERIFIER(new ComputeWorkGroupSizeCase			(m_context, verifier, (std::string("compute_work_group_size_") + verifierSuffix).c_str(),		"Test COMPUTE_WORK_GROUP_SIZE"));
    832 	FOR_EACH_INT_VERIFIER(new ActiveAtomicCounterBuffersCase	(m_context, verifier, (std::string("active_atomic_counter_buffers_") + verifierSuffix).c_str(),	"Test ACTIVE_ATOMIC_COUNTER_BUFFERS"));
    833 	FOR_EACH_INT_VERIFIER(new GeometryShaderCase				(m_context, verifier, (std::string("geometry_shader_state_") + verifierSuffix).c_str(),			"Test Geometry Shader State"));
    834 	FOR_EACH_INT_VERIFIER(new TessellationShaderCase			(m_context, verifier, (std::string("tesselation_shader_state_") + verifierSuffix).c_str(),		"Test Tesselation Shader State"));
    835 
    836 #undef FOR_EACH_INT_VERIFIER
    837 #undef FOR_EACH_VEC_VERIFIER
    838 
    839 	// program info log tests
    840 	// \note, there exists similar tests in gles3 module. However, the gles31 could use a different
    841 	//        shader compiler with different INFO_LOG bugs.
    842 	{
    843 		static const struct
    844 		{
    845 			const char*						caseName;
    846 			ProgramLogCase::BuildErrorType	caseType;
    847 		} shaderTypes[] =
    848 		{
    849 			{ "info_log_vertex_fragment_link_fail",		ProgramLogCase::BUILDERROR_VERTEX_FRAGMENT	},
    850 			{ "info_log_compute_link_fail",				ProgramLogCase::BUILDERROR_COMPUTE			},
    851 			{ "info_log_geometry_link_fail",			ProgramLogCase::BUILDERROR_GEOMETRY			},
    852 			{ "info_log_tessellation_link_fail",		ProgramLogCase::BUILDERROR_TESSELLATION		},
    853 		};
    854 
    855 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(shaderTypes); ++ndx)
    856 			addChild(new ProgramLogCase(m_context, shaderTypes[ndx].caseName, "", shaderTypes[ndx].caseType));
    857 	}
    858 }
    859 
    860 } // Functional
    861 } // gles31
    862 } // deqp
    863