1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2014-2016 The Khronos Group Inc.
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
22  */ /*-------------------------------------------------------------------*/
23 
24 #include "esextcGeometryShaderConstantVariables.hpp"
25 #include "gluContextInfo.hpp"
26 #include "gluDefs.hpp"
27 #include "glwEnums.hpp"
28 #include "glwFunctions.hpp"
29 #include "tcuTestLog.hpp"
30 
31 namespace glcts
32 {
33 
34 /* Fragment shader code */
35 const char *GeometryShaderConstantVariables::m_fragment_shader_code = "${VERSION}\n"
36                                                                       "\n"
37                                                                       "precision highp float;\n"
38                                                                       "\n"
39                                                                       "out vec4 color;\n"
40                                                                       "\n"
41                                                                       "void main()\n"
42                                                                       "{\n"
43                                                                       "   color = vec4(1, 1, 1, 1);\n"
44                                                                       "}\n";
45 
46 /* Geometry shader code */
47 const char *GeometryShaderConstantVariables::m_geometry_shader_code =
48     "${VERSION}\n"
49     "\n"
50     "${GEOMETRY_SHADER_REQUIRE}\n"
51     "\n"
52     "precision highp float;\n"
53     "\n"
54     "layout(points)                 in;\n"
55     "layout(points, max_vertices=1) out;\n"
56     "\n"
57     "flat out int test_MaxGeometryInputComponents;\n"
58     "flat out int test_MaxGeometryOutputComponents;\n"
59     "flat out int test_MaxGeometryTextureImageUnits;\n"
60     "flat out int test_MaxGeometryOutputVertices;\n"
61     "flat out int test_MaxGeometryTotalOutputComponents;\n"
62     "flat out int test_MaxGeometryUniformComponents;\n"
63     "flat out int test_MaxGeometryAtomicCounters;\n"
64     "flat out int test_MaxGeometryAtomicCounterBuffers;\n"
65     "flat out int test_MaxGeometryImageUniforms;\n"
66     "\n"
67     "void main()\n"
68     "{\n"
69     "   test_MaxGeometryInputComponents       = gl_MaxGeometryInputComponents;\n"
70     "   test_MaxGeometryOutputComponents      = gl_MaxGeometryOutputComponents;\n"
71     "   test_MaxGeometryTextureImageUnits     = gl_MaxGeometryTextureImageUnits;\n"
72     "   test_MaxGeometryOutputVertices        = gl_MaxGeometryOutputVertices;\n"
73     "   test_MaxGeometryTotalOutputComponents = gl_MaxGeometryTotalOutputComponents;\n"
74     "   test_MaxGeometryUniformComponents     = gl_MaxGeometryUniformComponents;\n"
75     "   test_MaxGeometryAtomicCounters        = gl_MaxGeometryAtomicCounters;\n"
76     "   test_MaxGeometryAtomicCounterBuffers  = gl_MaxGeometryAtomicCounterBuffers;\n"
77     "   test_MaxGeometryImageUniforms         = gl_MaxGeometryImageUniforms;\n"
78     "\n"
79     "   EmitVertex();\n"
80     "   EndPrimitive();\n"
81     "}\n";
82 
83 /* Vertex shader code */
84 const char *GeometryShaderConstantVariables::m_vertex_shader_code = "${VERSION}\n"
85                                                                     "\n"
86                                                                     "precision highp float;\n"
87                                                                     "\n"
88                                                                     "void main()\n"
89                                                                     "{\n"
90                                                                     "}\n";
91 
92 /* Specify transform feedback varyings */
93 const char *GeometryShaderConstantVariables::m_feedbackVaryings[] = {
94     "test_MaxGeometryInputComponents", "test_MaxGeometryOutputComponents",      "test_MaxGeometryTextureImageUnits",
95     "test_MaxGeometryOutputVertices",  "test_MaxGeometryTotalOutputComponents", "test_MaxGeometryUniformComponents",
96     "test_MaxGeometryAtomicCounters",  "test_MaxGeometryAtomicCounterBuffers",  "test_MaxGeometryImageUniforms"};
97 
98 /** Constructor
99  *
100  * @param context     Test context
101  * @param name        Test case's name
102  * @param description Test case's desricption
103  **/
GeometryShaderConstantVariables(Context & context,const ExtParameters & extParams,const char * name,const char * description)104 GeometryShaderConstantVariables::GeometryShaderConstantVariables(Context &context, const ExtParameters &extParams,
105                                                                  const char *name, const char *description)
106     : TestCaseBase(context, extParams, name, description)
107     , m_fragment_shader_id(0)
108     , m_geometry_shader_id(0)
109     , m_vertex_shader_id(0)
110     , m_program_id(0)
111     , m_bo_id(0)
112     , m_vao_id(0)
113     , m_min_MaxGeometryImagesUniforms(0)
114     , m_min_MaxGeometryTextureImagesUnits(16)
115     , m_min_MaxGeometryShaderStorageBlocks(0)
116     , m_min_MaxGeometryAtomicCounterBuffers(0)
117     , m_min_MaxGeometryAtomicCounters(0)
118     , m_min_MaxFramebufferLayers(256)
119     , m_min_MaxGeometryInputComponents(64)
120     , m_min_MaxGeometryOutputComponents(64)
121     , m_min_MaxGeometryOutputVertices(256)
122     , m_min_MaxGeometryShaderInvocations(32)
123     , m_min_MaxGeometryTotalOutputComponents(1024)
124     , m_min_MaxGeometryUniformBlocks(12)
125     , m_min_MaxGeometryUniformComponents(1024)
126 {
127     /* Left blank intentionally */
128 }
129 
130 /** Initializes GLES objects used during the test.
131  *
132  **/
initTest(void)133 void GeometryShaderConstantVariables::initTest(void)
134 {
135     /* This test should only run if EXT_geometry_shader is supported */
136     if (!m_is_geometry_shader_extension_supported)
137     {
138         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
139     }
140 
141     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
142 
143     /* Create VAO */
144     gl.genVertexArrays(1, &m_vao_id);
145 
146     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create VAO!");
147 
148     /* Create a program object and set it up for TF */
149     const unsigned int n_varyings = sizeof(m_feedbackVaryings) / sizeof(m_feedbackVaryings[0]);
150 
151     m_program_id = gl.createProgram();
152 
153     gl.transformFeedbackVaryings(m_program_id, n_varyings, m_feedbackVaryings, GL_INTERLEAVED_ATTRIBS);
154 
155     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set program object for transform feedback");
156 
157     /* Create shaders */
158     m_vertex_shader_id   = gl.createShader(GL_VERTEX_SHADER);
159     m_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
160     m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
161 
162     /* Build the test program */
163     if (!buildProgram(m_program_id, m_fragment_shader_id, 1, &m_fragment_shader_code, m_geometry_shader_id, 1,
164                       &m_geometry_shader_code, m_vertex_shader_id, 1, &m_vertex_shader_code))
165     {
166         TCU_FAIL("Program could not have been created from a valid vertex/geometry/fragment shader!");
167     }
168 
169     /* Create and set up a buffer object we will use for the test */
170     gl.genBuffers(1, &m_bo_id);
171     gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id);
172     gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLint) * n_varyings, DE_NULL, GL_STATIC_COPY);
173     gl.bindBuffer(GL_ARRAY_BUFFER, 0);
174 
175     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not set a buffer object up");
176 }
177 
178 /** Executes the test.
179  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
180  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
181  *  Note the function throws exception should an error occur!
182  **/
iterate(void)183 tcu::TestNode::IterateResult GeometryShaderConstantVariables::iterate(void)
184 {
185     initTest();
186 
187     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
188 
189     /* Set up relevant bindings */
190     gl.bindVertexArray(m_vao_id);
191     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind a vertex array object");
192 
193     gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_id);
194     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind a buffer object!");
195 
196     gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_id);
197     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not bind buffer object to transform feedback binding point.");
198 
199     /* Prepare for rendering. */
200     gl.useProgram(m_program_id);
201     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not use program");
202 
203     gl.enable(GL_RASTERIZER_DISCARD);
204 
205     gl.beginTransformFeedback(GL_POINTS);
206     {
207         /* Render */
208         gl.drawArrays(GL_POINTS, 0 /* first */, 1 /* count */);
209     }
210     gl.endTransformFeedback();
211     GLU_EXPECT_NO_ERROR(gl.getError(), "Rendering failed.");
212 
213     gl.disable(GL_RASTERIZER_DISCARD);
214 
215     /* First, retrieve the ES constant values using the API. */
216     const unsigned int n_varyings          = sizeof(m_feedbackVaryings) / sizeof(m_feedbackVaryings[0]);
217     glw::GLint constant_values[n_varyings] = {0};
218     unsigned int index                     = 0;
219 
220     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_INPUT_COMPONENTS, &constant_values[index]);
221     index++;
222     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT failed.");
223 
224     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_OUTPUT_COMPONENTS, &constant_values[index]);
225     index++;
226     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT failed.");
227 
228     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &constant_values[index]);
229     index++;
230     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT failed.");
231 
232     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_OUTPUT_VERTICES, &constant_values[index]);
233     index++;
234     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT failed.");
235 
236     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &constant_values[index]);
237     index++;
238     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT failed.");
239 
240     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_UNIFORM_COMPONENTS, &constant_values[index]);
241     index++;
242     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT failed.");
243 
244     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTERS, &constant_values[index]);
245     index++;
246     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT failed.");
247 
248     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS, &constant_values[index]);
249     index++;
250     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT failed.");
251 
252     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_IMAGE_UNIFORMS, &constant_values[index]);
253     index++;
254     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() for GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT failed.");
255 
256     const glw::GLint *stored_data_ptr = (const glw::GLint *)gl.mapBufferRange(
257         GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(glw::GLint) * n_varyings, GL_MAP_READ_BIT);
258 
259     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not map buffer object storage");
260 
261     /* Compare the values that were stored by the draw call with values
262      * returned by the getter call.
263      */
264     bool has_failed = false;
265     for (unsigned int id = 0; id < n_varyings; ++id)
266     {
267         if (constant_values[id] != stored_data_ptr[id])
268         {
269             m_testCtx.getLog() << tcu::TestLog::Message << "Values reported for ES constant " << m_feedbackVaryings[id]
270                                << " in a shader: " << stored_data_ptr[id]
271                                << " and via a glGetIntegerv() call: " << constant_values[id] << " do not match."
272                                << tcu::TestLog::EndMessage;
273             has_failed = true;
274         }
275     }
276 
277     gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
278 
279     /* Check whether the reported values are at least of the minimum value described in relevant
280      * extension specifications */
281 
282     glw::GLint int_value = 0;
283 
284     /* Check values of ES constants specific to shader atomic counters */
285     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS, &int_value);
286 
287     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT");
288 
289     if (int_value < m_min_MaxGeometryAtomicCounterBuffers)
290     {
291         m_testCtx.getLog() << tcu::TestLog::Message
292                            << "Reported GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT constant value " << int_value
293                            << " is smaller than required minimum value of " << m_min_MaxGeometryAtomicCounterBuffers
294                            << tcu::TestLog::EndMessage;
295 
296         has_failed = true;
297     }
298 
299     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTERS, &int_value);
300 
301     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT");
302 
303     if (int_value < m_min_MaxGeometryAtomicCounters)
304     {
305         m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT constant value "
306                            << int_value << " is smaller than required minimum value of "
307                            << m_min_MaxGeometryAtomicCounters << tcu::TestLog::EndMessage;
308 
309         has_failed = true;
310     }
311 
312     /* Check values of ES constants specific to image load store */
313     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_IMAGE_UNIFORMS, &int_value);
314 
315     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT");
316 
317     if (int_value < m_min_MaxGeometryImagesUniforms)
318     {
319         m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT constant value "
320                            << int_value << " is smaller than required minimum value of "
321                            << m_min_MaxGeometryImagesUniforms << tcu::TestLog::EndMessage;
322 
323         has_failed = true;
324     }
325 
326     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_TEXTURE_IMAGE_UNITS, &int_value);
327 
328     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT");
329 
330     if (int_value < m_min_MaxGeometryTextureImagesUnits)
331     {
332         m_testCtx.getLog() << tcu::TestLog::Message
333                            << "Reported GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT constant value " << int_value
334                            << " is smaller than required minimum value of " << m_min_MaxGeometryTextureImagesUnits
335                            << tcu::TestLog::EndMessage;
336 
337         has_failed = true;
338     }
339 
340     /* Check values of ES constants specific to shader storage buffer objects */
341     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &int_value);
342 
343     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT");
344 
345     if (int_value < m_min_MaxGeometryShaderStorageBlocks)
346     {
347         m_testCtx.getLog() << tcu::TestLog::Message
348                            << "Reported GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT constant value " << int_value
349                            << " is smaller than required minimum value of " << m_min_MaxGeometryShaderStorageBlocks
350                            << tcu::TestLog::EndMessage;
351 
352         has_failed = true;
353     }
354 
355     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_UNIFORM_COMPONENTS, &int_value);
356 
357     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT");
358 
359     if (int_value < m_min_MaxGeometryUniformComponents)
360     {
361         m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT constant value "
362                            << int_value << " is smaller than required minimum value of "
363                            << m_min_MaxGeometryUniformComponents << tcu::TestLog::EndMessage;
364 
365         has_failed = true;
366     }
367 
368     /* Check EXT_geometry_shader specific constant values */
369     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_UNIFORM_BLOCKS, &int_value);
370 
371     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT");
372 
373     if (int_value < m_min_MaxGeometryUniformBlocks)
374     {
375         m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT constant value "
376                            << int_value << " is smaller than required minimum value of "
377                            << m_min_MaxGeometryUniformBlocks << tcu::TestLog::EndMessage;
378 
379         has_failed = true;
380     }
381 
382     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_INPUT_COMPONENTS, &int_value);
383 
384     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT");
385 
386     if (int_value < m_min_MaxGeometryInputComponents)
387     {
388         m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT constant value "
389                            << int_value << " is smaller than required minimum value of "
390                            << m_min_MaxGeometryInputComponents << tcu::TestLog::EndMessage;
391 
392         has_failed = true;
393     }
394 
395     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_OUTPUT_COMPONENTS, &int_value);
396 
397     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT");
398 
399     if (int_value < m_min_MaxGeometryOutputComponents)
400     {
401         m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT constant value "
402                            << int_value << " is smaller than required minimum value of "
403                            << m_min_MaxGeometryOutputComponents << tcu::TestLog::EndMessage;
404 
405         has_failed = true;
406     }
407 
408     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_OUTPUT_VERTICES, &int_value);
409 
410     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT");
411 
412     if (int_value < m_min_MaxGeometryOutputVertices)
413     {
414         m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT constant value "
415                            << int_value << " is smaller than required minimum value of "
416                            << m_min_MaxGeometryOutputVertices << tcu::TestLog::EndMessage;
417 
418         has_failed = true;
419     }
420 
421     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS, &int_value);
422 
423     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT");
424 
425     if (int_value < m_min_MaxGeometryTotalOutputComponents)
426     {
427         m_testCtx.getLog() << tcu::TestLog::Message
428                            << "Reported GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT constant value " << int_value
429                            << " is smaller than required minimum value of " << m_min_MaxGeometryTotalOutputComponents
430                            << tcu::TestLog::EndMessage;
431 
432         has_failed = true;
433     }
434 
435     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_SHADER_INVOCATIONS, &int_value);
436 
437     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT");
438 
439     if (int_value < m_min_MaxGeometryShaderInvocations)
440     {
441         m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT constant value "
442                            << int_value << " is smaller than required minimum value of "
443                            << m_min_MaxGeometryShaderInvocations << tcu::TestLog::EndMessage;
444 
445         has_failed = true;
446     }
447 
448     gl.getIntegerv(m_glExtTokens.MAX_FRAMEBUFFER_LAYERS, &int_value);
449 
450     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_FRAMEBUFFER_LAYERS_EXT");
451 
452     if (int_value < m_min_MaxFramebufferLayers)
453     {
454         m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_MAX_FRAMEBUFFER_LAYERS_EXT constant value "
455                            << int_value << " is smaller than required minimum value of " << m_min_MaxFramebufferLayers
456                            << tcu::TestLog::EndMessage;
457 
458         has_failed = true;
459     }
460 
461     /* Compute minimum value that is acceptable for gl_MaxCombinedGeometryUniformComponents */
462     glw::GLint n_max_geometry_uniform_blocks     = 0;
463     glw::GLint n_max_geometry_uniform_block_size = 0;
464     glw::GLint n_max_geometry_uniform_components = 0;
465 
466     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_UNIFORM_BLOCKS, &n_max_geometry_uniform_blocks);
467 
468     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT.");
469 
470     gl.getIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &n_max_geometry_uniform_block_size);
471 
472     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_UNIFORM_BLOCK_SIZE.");
473 
474     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_UNIFORM_COMPONENTS, &n_max_geometry_uniform_components);
475 
476     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT.");
477 
478     glw::GLint n_max_combined_geometry_uniform_components =
479         n_max_geometry_uniform_blocks * n_max_geometry_uniform_block_size / 4 + n_max_geometry_uniform_components;
480 
481     /* Compare against actual constant value */
482     gl.getIntegerv(m_glExtTokens.MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS, &int_value);
483 
484     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT.");
485 
486     if (int_value < n_max_combined_geometry_uniform_components)
487     {
488         m_testCtx.getLog() << tcu::TestLog::Message
489                            << "Reported GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT constant value " << int_value
490                            << " is smaller than required minimum value of "
491                            << n_max_combined_geometry_uniform_components << tcu::TestLog::EndMessage;
492 
493         has_failed = true;
494     }
495 
496     /* Make sure value reported for GL_LAYER_PROVOKING_VERTEX_EXT is valid */
497     gl.getIntegerv(m_glExtTokens.LAYER_PROVOKING_VERTEX, &int_value);
498 
499     GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv() failed for GL_LAYER_PROVOKING_VERTEX_EXT.");
500 
501     if (
502         /* This value is allowed in Desktop OpenGL, but not in the ES 3.1 extension. */
503         (!glu::isContextTypeES(m_context.getRenderContext().getType()) &&
504          (glw::GLenum)int_value != GL_PROVOKING_VERTEX) &&
505         (glw::GLenum)int_value != m_glExtTokens.FIRST_VERTEX_CONVENTION &&
506         (glw::GLenum)int_value != m_glExtTokens.LAST_VERTEX_CONVENTION &&
507         (glw::GLenum)int_value != m_glExtTokens.UNDEFINED_VERTEX)
508     {
509         m_testCtx.getLog() << tcu::TestLog::Message << "Reported GL_LAYER_PROVOKING_VERTEX_EXT constant value "
510                            << int_value << " is not among permissible values" << tcu::TestLog::EndMessage;
511 
512         has_failed = true;
513     }
514 
515     if (has_failed)
516     {
517         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
518 
519         return STOP;
520     }
521 
522     m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
523 
524     return STOP;
525 }
526 
527 /** Deinitializes GLES objects created during the test.
528  *
529  */
deinit(void)530 void GeometryShaderConstantVariables::deinit(void)
531 {
532     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
533 
534     /* Reset OpenGL ES state */
535     gl.useProgram(0);
536     gl.bindBuffer(GL_ARRAY_BUFFER, 0);
537     gl.bindVertexArray(0);
538 
539     /* Delete program object and shaders */
540     if (m_program_id != 0)
541     {
542         gl.deleteProgram(m_program_id);
543 
544         m_program_id = 0;
545     }
546 
547     if (m_vertex_shader_id != 0)
548     {
549         gl.deleteShader(m_vertex_shader_id);
550 
551         m_vertex_shader_id = 0;
552     }
553 
554     if (m_geometry_shader_id != 0)
555     {
556         gl.deleteShader(m_geometry_shader_id);
557 
558         m_geometry_shader_id = 0;
559     }
560 
561     if (m_fragment_shader_id != 0)
562     {
563         gl.deleteShader(m_fragment_shader_id);
564 
565         m_fragment_shader_id = 0;
566     }
567 
568     if (m_bo_id != 0)
569     {
570         gl.deleteBuffers(1, &m_bo_id);
571 
572         m_bo_id = 0;
573     }
574 
575     if (m_vao_id != 0)
576     {
577         gl.deleteVertexArrays(1, &m_vao_id);
578 
579         m_vao_id = 0;
580     }
581 
582     /* Release base class */
583     TestCaseBase::deinit();
584 }
585 
586 } // namespace glcts
587