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