• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getVerifierSuffix(QueryType type)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 
GeometryShaderCase(Context & context,QueryType verifier,const char * name,const char * desc)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 
iterate(void)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 
TessellationShaderCase(Context & context,QueryType verifier,const char * name,const char * desc)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 
iterate(void)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 
ProgramSeparableCase(Context & context,QueryType verifier,const char * name,const char * desc)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 
iterate(void)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 
ComputeWorkGroupSizeCase(Context & context,QueryType verifier,const char * name,const char * desc)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 
iterate(void)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 
ActiveAtomicCounterBuffersCase(Context & context,QueryType verifier,const char * name,const char * desc)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 
iterate(void)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 
ProgramLogCase(Context & ctx,const char * name,const char * desc,BuildErrorType errorType)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 
init(void)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 
iterate(void)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 
getProgramSources(void) const689 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 
ProgramStateQueryTests(Context & context)796 ProgramStateQueryTests::ProgramStateQueryTests (Context& context)
797 	: TestCaseGroup(context, "program", "Program State Query tests")
798 {
799 }
800 
~ProgramStateQueryTests(void)801 ProgramStateQueryTests::~ProgramStateQueryTests (void)
802 {
803 }
804 
init(void)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