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