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
36namespace deqp
37{
38
39using std::string;
40using std::map;
41
42namespace gles31
43{
44namespace Functional
45{
46namespace
47{
48
49using namespace gls::StateQueryUtil;
50
51static 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
65class GeometryShaderCase : public TestCase
66{
67public:
68						GeometryShaderCase		(Context& context, QueryType verifier, const char* name, const char* desc);
69	IterateResult		iterate					(void);
70
71private:
72	const QueryType		m_verifier;
73};
74
75GeometryShaderCase::GeometryShaderCase (Context& context, QueryType verifier, const char* name, const char* desc)
76	: TestCase		(context, name, desc)
77	, m_verifier	(verifier)
78{
79}
80
81GeometryShaderCase::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
183class TessellationShaderCase : public TestCase
184{
185public:
186						TessellationShaderCase		(Context& context, QueryType verifier, const char* name, const char* desc);
187	IterateResult		iterate					(void);
188
189private:
190	const QueryType		m_verifier;
191};
192
193TessellationShaderCase::TessellationShaderCase (Context& context, QueryType verifier, const char* name, const char* desc)
194	: TestCase		(context, name, desc)
195	, m_verifier	(verifier)
196{
197}
198
199TessellationShaderCase::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
317class ProgramSeparableCase : public TestCase
318{
319public:
320						ProgramSeparableCase	(Context& context, QueryType verifier, const char* name, const char* desc);
321	IterateResult		iterate					(void);
322
323private:
324	const QueryType		m_verifier;
325};
326
327ProgramSeparableCase::ProgramSeparableCase (Context& context, QueryType verifier, const char* name, const char* desc)
328	: TestCase		(context, name, desc)
329	, m_verifier	(verifier)
330{
331}
332
333ProgramSeparableCase::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
430class ComputeWorkGroupSizeCase : public TestCase
431{
432public:
433						ComputeWorkGroupSizeCase	(Context& context, QueryType verifier, const char* name, const char* desc);
434	IterateResult		iterate						(void);
435
436private:
437	const QueryType		m_verifier;
438};
439
440ComputeWorkGroupSizeCase::ComputeWorkGroupSizeCase (Context& context, QueryType verifier, const char* name, const char* desc)
441	: TestCase		(context, name, desc)
442	, m_verifier	(verifier)
443{
444}
445
446ComputeWorkGroupSizeCase::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
530class ActiveAtomicCounterBuffersCase : public TestCase
531{
532public:
533						ActiveAtomicCounterBuffersCase	(Context& context, QueryType verifier, const char* name, const char* desc);
534	IterateResult		iterate							(void);
535
536private:
537	const QueryType		m_verifier;
538};
539
540ActiveAtomicCounterBuffersCase::ActiveAtomicCounterBuffersCase (Context& context, QueryType verifier, const char* name, const char* desc)
541	: TestCase		(context, name, desc)
542	, m_verifier	(verifier)
543{
544}
545
546ActiveAtomicCounterBuffersCase::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
615class ProgramLogCase : public TestCase
616{
617public:
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
628private:
629	void					init				(void);
630	IterateResult			iterate				(void);
631	glu::ProgramSources		getProgramSources	(void) const;
632
633	const BuildErrorType	m_buildErrorType;
634};
635
636ProgramLogCase::ProgramLogCase (Context& ctx, const char* name, const char* desc, BuildErrorType errorType)
637	: TestCase			(ctx, name, desc)
638	, m_buildErrorType	(errorType)
639{
640}
641
642void 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
666ProgramLogCase::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
689glu::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
796ProgramStateQueryTests::ProgramStateQueryTests (Context& context)
797	: TestCaseGroup(context, "program", "Program State Query tests")
798{
799}
800
801ProgramStateQueryTests::~ProgramStateQueryTests (void)
802{
803}
804
805void 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