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