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 "esextcGeometryShaderProgramResource.hpp"
25 #include "gluContextInfo.hpp"
26 #include "glwEnums.hpp"
27 #include "glwFunctions.hpp"
28 #include "tcuTestLog.hpp"
29 
30 namespace glcts
31 {
32 /* Shared shaders' code */
33 const char *const GeometryShaderProgramResourceTest::m_common_shader_code_definitions_body =
34     "// uniforms\n"
35     "uniform mat4 uni_model_view_projection; // not referenced in GS\n"
36     "uniform vec4 uni_colors_white;          // referenced in GS\n"
37     "\n"
38     "// uniforms blocks\n"
39     "uniform Matrices\n"
40     "{\n"
41     "    mat4 model;\n"
42     "    mat4 view;\n"
43     "    mat4 projection;\n"
44     "} uni_matrices; // not referenced at all\n"
45     "\n"
46     "uniform Colors\n"
47     "{\n"
48     "    vec4 red;\n"
49     "    vec4 green;\n"
50     "    vec4 blue;\n"
51     "} uni_colors; // referenced in GS\n"
52     "\n";
53 
54 const char *const GeometryShaderProgramResourceTest::m_common_shader_code_definitions_atomic_counter_body =
55     "// atomic counter buffers\n"
56     "layout (binding = 0) uniform atomic_uint uni_atom_horizontal; // not referenced in GS\n"
57     "layout (binding = 1) uniform atomic_uint uni_atom_vertical;   // referenced in GS\n"
58     "\n";
59 
60 const char *const GeometryShaderProgramResourceTest::m_common_shader_code_definitions_ssbo_body =
61     "// ssbos\n"
62     "buffer Positions\n"
63     "{\n"
64     "    vec4 position[4]; // referenced in GS\n"
65     "} storage_positions;  // referenced in GS\n"
66     "\n"
67     "buffer Ids\n"
68     "{\n"
69     "    int ids[4]; // not referenced in GS\n"
70     "} storage_ids;  // not referenced in GS\n"
71     "\n";
72 
73 /* Vertex shader */
74 const char *const GeometryShaderProgramResourceTest::m_vertex_shader_code_preamble = "${VERSION}\n"
75                                                                                      "\n"
76                                                                                      "precision highp float;\n"
77                                                                                      "\n"
78                                                                                      "// uniforms included here\n";
79 
80 const char *const GeometryShaderProgramResourceTest::m_vertex_shader_code_body =
81     "// attributes\n"
82     "in vec4 vs_in_position; // not referenced in GS\n"
83     "in vec4 vs_in_color;    // not referenced in GS\n"
84     "\n"
85     "// output\n"
86     "out vec4 vs_out_color; // referenced in GS\n"
87     "\n"
88     "void main()\n"
89     "{\n"
90     "    gl_Position  = uni_model_view_projection * vs_in_position;\n"
91     "    vs_out_color = vs_in_color;\n";
92 
93 const char *const GeometryShaderProgramResourceTest::m_vertex_shader_code_atomic_counter_body =
94     "    // write atomic counters\n"
95     "    if (0.0 <= gl_Position.x)\n"
96     "    {\n"
97     "        atomicCounterIncrement(uni_atom_vertical);\n"
98     "    }\n"
99     "\n"
100     "    if (0.0 <= gl_Position.y)\n"
101     "    {\n"
102     "        atomicCounterIncrement(uni_atom_horizontal);\n"
103     "    }\n";
104 
105 const char *const GeometryShaderProgramResourceTest::m_vertex_shader_code_ssbo_body =
106     "    // write shader storage buffers\n"
107     "    storage_positions.position[gl_VertexID] = gl_Position;\n"
108     "    storage_ids.ids[gl_VertexID]            = gl_VertexID;\n";
109 
110 /* Geometry shader */
111 const char *const GeometryShaderProgramResourceTest::m_geometry_shader_code_preamble =
112     "${VERSION}\n"
113     "\n"
114     "${GEOMETRY_SHADER_REQUIRE}\n"
115     "\n"
116     "precision highp float;\n"
117     "\n"
118     "layout (points)                           in;\n"
119     "layout (triangle_strip, max_vertices = 6) out;\n"
120     "\n"
121     "// uniforms included here\n";
122 
123 const char *const GeometryShaderProgramResourceTest::m_geometry_shader_code_body =
124     "// input from vs + gl_Position\n"
125     "in vec4 vs_out_color[1];\n"
126     "\n"
127     "out vec4 gs_out_color;\n"
128     "\n"
129     "void main()\n"
130     "{\n"
131     "    // access uniform\n"
132     "    gl_Position = vec4(0, 0, 0, 0);\n"
133     "    gs_out_color = uni_colors_white;\n"
134     "    EmitVertex();\n"
135     "\n"
136     "    // access uniform block\n"
137     "    gl_Position = gl_in[0].gl_Position + vec4(-0.1, 0.1, 0, 0);\n"
138     "    gs_out_color = vs_out_color[0] + uni_colors.red;\n"
139     "    EmitVertex();\n"
140     "\n"
141     "    gl_Position = gl_in[0].gl_Position + vec4(-0.1, -0.1, 0, 0);\n"
142     "    gs_out_color = vs_out_color[0] + uni_colors.green;\n"
143     "    EmitVertex();\n"
144     "\n"
145     "    gl_Position = gl_in[0].gl_Position + vec4(0.1, -0.1, 0, 0);\n"
146     "    gs_out_color = vs_out_color[0] + uni_colors.blue;\n"
147     "    EmitVertex();\n";
148 
149 const char *const GeometryShaderProgramResourceTest::m_geometry_shader_code_atomic_counter_body =
150     "    // access atomic counter\n"
151     "    gl_Position = vec4(0, 0, 0, 0);\n"
152     "    uint  counter = atomicCounter(uni_atom_vertical);\n"
153     "    gs_out_color     = vec4(counter / 255u);\n"
154     "    EmitVertex();\n";
155 
156 const char *const GeometryShaderProgramResourceTest::m_geometry_shader_code_ssbo_body =
157     "    // access shader storage buffers\n"
158     "    gl_Position = storage_positions.position[0] + vec4(0.1, 0.1, 0, 0);\n"
159     "    gs_out_color     = vec4(1.0);\n"
160     "    EmitVertex();\n";
161 
162 /* Fragment shader */
163 const char *const GeometryShaderProgramResourceTest::m_fragment_shader_code =
164     "${VERSION}\n"
165     "\n"
166     "precision highp float;\n"
167     "\n"
168     "// input from gs\n"
169     "in vec4 gs_out_color;\n"
170     "layout(location = 0) out vec4 fs_out_color;\n"
171     "\n"
172     "void main()\n"
173     "{\n"
174     "    fs_out_color = gs_out_color;\n"
175     "}\n"
176     "\n";
177 
178 /** Constructor
179  *
180  * @param context     Test context
181  * @param name        Test case's name
182  * @param description Test case's desricption
183  **/
GeometryShaderProgramResourceTest(Context & context,const ExtParameters & extParams,const char * name,const char * description)184 GeometryShaderProgramResourceTest::GeometryShaderProgramResourceTest(Context &context, const ExtParameters &extParams,
185                                                                      const char *name, const char *description)
186     : TestCaseBase(context, extParams, name, description)
187     , m_fragment_shader_id(0)
188     , m_geometry_shader_id(0)
189     , m_vertex_shader_id(0)
190     , m_program_object_id(0)
191     , m_atomic_counters_supported(false)
192     , m_ssbos_supported(false)
193 {
194     /* Nothing to be done here */
195 }
196 
197 /** Initializes GLES objects used during the test.
198  *
199  **/
initTest()200 void GeometryShaderProgramResourceTest::initTest()
201 {
202     /* Check if geometry_shader extension is supported */
203     if (!m_is_geometry_shader_extension_supported)
204     {
205         throw tcu::NotSupportedError(GEOMETRY_SHADER_EXTENSION_NOT_SUPPORTED, "", __FILE__, __LINE__);
206     }
207 
208     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
209 
210     glw::GLint maxVSAtomicCounters = 0;
211     gl.getIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS, &maxVSAtomicCounters);
212 
213     glw::GLint maxGSAtomicCounters = 0;
214     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS, &maxGSAtomicCounters);
215 
216     m_atomic_counters_supported = maxVSAtomicCounters >= 2 && maxGSAtomicCounters >= 1;
217 
218     glw::GLint maxVSStorageBlocks = 0;
219     gl.getIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &maxVSStorageBlocks);
220 
221     glw::GLint maxGSStorageBlocks = 0;
222     gl.getIntegerv(m_glExtTokens.MAX_GEOMETRY_SHADER_STORAGE_BLOCKS, &maxGSStorageBlocks);
223 
224     m_ssbos_supported = maxVSStorageBlocks >= 2 && maxGSStorageBlocks >= 1;
225 
226     glw::GLuint nCodeParts = 0;
227     const char *vertex_shader_code_parts[8];
228     const char *geometry_shader_code_parts[8];
229 
230     /* Vertex & geometry shaders */
231     if (m_atomic_counters_supported && m_ssbos_supported)
232     {
233         vertex_shader_code_parts[0] = m_vertex_shader_code_preamble;
234         vertex_shader_code_parts[1] = m_common_shader_code_definitions_body;
235         vertex_shader_code_parts[2] = m_common_shader_code_definitions_atomic_counter_body;
236         vertex_shader_code_parts[3] = m_common_shader_code_definitions_ssbo_body;
237         vertex_shader_code_parts[4] = m_vertex_shader_code_body;
238         vertex_shader_code_parts[5] = m_vertex_shader_code_atomic_counter_body;
239         vertex_shader_code_parts[6] = m_vertex_shader_code_ssbo_body;
240         vertex_shader_code_parts[7] = "}\n";
241 
242         geometry_shader_code_parts[0] = m_geometry_shader_code_preamble;
243         geometry_shader_code_parts[1] = m_common_shader_code_definitions_body;
244         geometry_shader_code_parts[2] = m_common_shader_code_definitions_atomic_counter_body;
245         geometry_shader_code_parts[3] = m_common_shader_code_definitions_ssbo_body;
246         geometry_shader_code_parts[4] = m_geometry_shader_code_body;
247         geometry_shader_code_parts[5] = m_geometry_shader_code_atomic_counter_body;
248         geometry_shader_code_parts[6] = m_geometry_shader_code_ssbo_body;
249         geometry_shader_code_parts[7] = "}\n";
250 
251         nCodeParts = 8;
252     }
253     else if (m_atomic_counters_supported)
254     {
255         vertex_shader_code_parts[0] = m_vertex_shader_code_preamble;
256         vertex_shader_code_parts[1] = m_common_shader_code_definitions_body;
257         vertex_shader_code_parts[2] = m_common_shader_code_definitions_atomic_counter_body;
258         vertex_shader_code_parts[3] = m_vertex_shader_code_body;
259         vertex_shader_code_parts[4] = m_vertex_shader_code_atomic_counter_body;
260         vertex_shader_code_parts[5] = "}\n";
261 
262         geometry_shader_code_parts[0] = m_geometry_shader_code_preamble;
263         geometry_shader_code_parts[1] = m_common_shader_code_definitions_body;
264         geometry_shader_code_parts[2] = m_common_shader_code_definitions_atomic_counter_body;
265         geometry_shader_code_parts[3] = m_geometry_shader_code_body;
266         geometry_shader_code_parts[4] = m_geometry_shader_code_atomic_counter_body;
267         geometry_shader_code_parts[5] = "}\n";
268 
269         nCodeParts = 6;
270     }
271     else if (m_ssbos_supported)
272     {
273         vertex_shader_code_parts[0] = m_vertex_shader_code_preamble;
274         vertex_shader_code_parts[1] = m_common_shader_code_definitions_body;
275         vertex_shader_code_parts[2] = m_common_shader_code_definitions_ssbo_body;
276         vertex_shader_code_parts[3] = m_vertex_shader_code_body;
277         vertex_shader_code_parts[4] = m_vertex_shader_code_ssbo_body;
278         vertex_shader_code_parts[5] = "}\n";
279 
280         geometry_shader_code_parts[0] = m_geometry_shader_code_preamble;
281         geometry_shader_code_parts[1] = m_common_shader_code_definitions_body;
282         geometry_shader_code_parts[2] = m_common_shader_code_definitions_ssbo_body;
283         geometry_shader_code_parts[3] = m_geometry_shader_code_body;
284         geometry_shader_code_parts[4] = m_geometry_shader_code_ssbo_body;
285         geometry_shader_code_parts[5] = "}\n";
286 
287         nCodeParts = 6;
288     }
289     else
290     {
291         vertex_shader_code_parts[0] = m_vertex_shader_code_preamble;
292         vertex_shader_code_parts[1] = m_common_shader_code_definitions_body;
293         vertex_shader_code_parts[2] = m_vertex_shader_code_body;
294         vertex_shader_code_parts[3] = "}\n";
295 
296         geometry_shader_code_parts[0] = m_geometry_shader_code_preamble;
297         geometry_shader_code_parts[1] = m_common_shader_code_definitions_body;
298         geometry_shader_code_parts[2] = m_geometry_shader_code_body;
299         geometry_shader_code_parts[3] = "}\n";
300 
301         nCodeParts = 4;
302     }
303 
304     /* Create shader objects */
305     m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
306     m_geometry_shader_id = gl.createShader(m_glExtTokens.GEOMETRY_SHADER);
307     m_vertex_shader_id   = gl.createShader(GL_VERTEX_SHADER);
308 
309     /* Create program object */
310     m_program_object_id = gl.createProgram();
311 
312     GLU_EXPECT_NO_ERROR(gl.getError(), "Could not create program object");
313 
314     /* Build program object */
315     if (true !=
316         buildProgram(m_program_object_id, m_fragment_shader_id, 1,               /* Fragment shader parts number */
317                      &m_fragment_shader_code, m_geometry_shader_id, nCodeParts,  /* Geometry shader parts number */
318                      geometry_shader_code_parts, m_vertex_shader_id, nCodeParts, /* Vertex shader parts number */
319                      vertex_shader_code_parts))
320     {
321         TCU_FAIL("Could not create program from valid vertex/geometry/fragment shader");
322     }
323 }
324 
325 /** Executes the test.
326  *  Sets the test result to QP_TEST_RESULT_FAIL if the test failed, QP_TEST_RESULT_PASS otherwise.
327  *  @return STOP if the test has finished, CONTINUE to indicate iterate should be called once again.
328  *  Note the function throws exception should an error occur!
329  **/
iterate()330 tcu::TestCase::IterateResult GeometryShaderProgramResourceTest::iterate()
331 {
332     initTest();
333 
334     /* Results */
335     bool result = true;
336 
337     /* Results of checks, names come from shaders */
338     bool is_gl_fs_out_color_program_output_referenced         = false;
339     bool is_ids_ids_buffer_variable_referenced                = false;
340     bool is_positions_position_buffer_variable_referenced     = false;
341     bool is_storage_ids_shader_storage_block_referenced       = false;
342     bool is_storage_positions_shader_storage_block_referenced = false;
343     bool is_uni_atom_horizontal_uniform_referenced            = false;
344     bool is_uni_atom_vertical_uniform_referenced              = false;
345     bool is_uni_colors_uniform_referenced                     = false;
346     bool is_uni_colors_white_uniform_referenced               = false;
347     bool is_uni_matrices_uniform_referenced                   = false;
348     bool is_uni_model_view_projection_uniform_referenced      = false;
349     bool is_vs_in_color_program_input_referenced              = false;
350     bool is_vs_in_position_program_input_referenced           = false;
351 
352     /* Check whether uniform variables are referenced */
353     is_uni_model_view_projection_uniform_referenced =
354         checkIfResourceIsReferenced(m_program_object_id, GL_UNIFORM, "uni_model_view_projection");
355     is_uni_colors_white_uniform_referenced =
356         checkIfResourceIsReferenced(m_program_object_id, GL_UNIFORM, "uni_colors_white");
357 
358     /* For: uniform Matrices {} uni_matrices; uniform block name is: Matrices */
359     is_uni_matrices_uniform_referenced = checkIfResourceIsReferenced(m_program_object_id, GL_UNIFORM_BLOCK, "Matrices");
360     is_uni_colors_uniform_referenced   = checkIfResourceIsReferenced(m_program_object_id, GL_UNIFORM_BLOCK, "Colors");
361 
362     /* For: buffer Positions {} storage_positions; storage block name is: Positions */
363     if (m_ssbos_supported)
364     {
365         is_storage_positions_shader_storage_block_referenced =
366             checkIfResourceIsReferenced(m_program_object_id, GL_SHADER_STORAGE_BLOCK, "Positions");
367         is_storage_ids_shader_storage_block_referenced =
368             checkIfResourceIsReferenced(m_program_object_id, GL_SHADER_STORAGE_BLOCK, "Ids");
369 
370         is_positions_position_buffer_variable_referenced =
371             checkIfResourceIsReferenced(m_program_object_id, GL_BUFFER_VARIABLE, "Positions.position");
372         is_ids_ids_buffer_variable_referenced =
373             checkIfResourceIsReferenced(m_program_object_id, GL_BUFFER_VARIABLE, "Ids.ids");
374     }
375 
376     /* Check whether input attributes are referenced */
377     is_vs_in_position_program_input_referenced =
378         checkIfResourceIsReferenced(m_program_object_id, GL_PROGRAM_INPUT, "vs_in_position");
379     is_vs_in_color_program_input_referenced =
380         checkIfResourceIsReferenced(m_program_object_id, GL_PROGRAM_INPUT, "vs_in_color");
381 
382     /* Check whether output attributes are referenced */
383     is_gl_fs_out_color_program_output_referenced =
384         checkIfResourceIsReferenced(m_program_object_id, GL_PROGRAM_OUTPUT, "fs_out_color");
385 
386     /*
387      *     For the ATOMIC_COUNTER_BUFFER interface, the list of active buffer binding
388      *     points is built by identifying each unique binding point associated with
389      *     one or more active atomic counter uniform variables.  Active atomic
390      *     counter buffers do not have an associated name string.
391      */
392     if (m_atomic_counters_supported)
393     {
394         const glw::Functions &gl = m_context.getRenderContext().getFunctions();
395 
396         /* First get corresponding uniform indices */
397         glw::GLuint atom_horizontal_uniform_indx =
398             gl.getProgramResourceIndex(m_program_object_id, GL_UNIFORM, "uni_atom_horizontal");
399         glw::GLuint atom_vertical_uniform_indx =
400             gl.getProgramResourceIndex(m_program_object_id, GL_UNIFORM, "uni_atom_vertical");
401 
402         /* Then get atomic buffer indices */
403         glw::GLuint atom_horizontal_uniform_buffer_indx = GL_INVALID_INDEX;
404         glw::GLuint atom_vertical_uniform_buffer_indx   = GL_INVALID_INDEX;
405 
406         /* Data for getProgramResourceiv */
407         glw::GLint params[] = {0};
408         glw::GLenum props[] = {GL_ATOMIC_COUNTER_BUFFER_INDEX};
409 
410         /* Get property value */
411         gl.getProgramResourceiv(m_program_object_id, GL_UNIFORM, atom_horizontal_uniform_indx, 1, /* propCount */
412                                 props, 1,                                                         /* bufSize */
413                                 0,                                                                /* length */
414                                 params);
415         atom_horizontal_uniform_buffer_indx = params[0];
416 
417         gl.getProgramResourceiv(m_program_object_id, GL_UNIFORM, atom_vertical_uniform_indx, 1, /* propCount */
418                                 props, 1,                                                       /* bufSize */
419                                 0,                                                              /* length */
420                                 params);
421         atom_vertical_uniform_buffer_indx = params[0];
422 
423         /* Check whether atomic counters are referenced using the atomic buffer indices */
424         is_uni_atom_horizontal_uniform_referenced = checkIfResourceAtIndexIsReferenced(
425             m_program_object_id, GL_ATOMIC_COUNTER_BUFFER, atom_horizontal_uniform_buffer_indx);
426         is_uni_atom_vertical_uniform_referenced = checkIfResourceAtIndexIsReferenced(
427             m_program_object_id, GL_ATOMIC_COUNTER_BUFFER, atom_vertical_uniform_buffer_indx);
428     }
429 
430     /* Verify results: referenced properties */
431     if (true != is_uni_colors_white_uniform_referenced)
432     {
433         m_testCtx.getLog() << tcu::TestLog::Message
434                            << "Wrong value of property GL_REFERENCED_BY_GEOMETRY_SHADER_EXT for GL_UNIFORM"
435                            << tcu::TestLog::EndMessage;
436 
437         result = false;
438     }
439 
440     if (true != is_uni_colors_uniform_referenced)
441     {
442         m_testCtx.getLog() << tcu::TestLog::Message
443                            << "Wrong value of property GL_REFERENCED_BY_GEOMETRY_SHADER_EXT for GL_UNIFORM_BLOCK"
444                            << tcu::TestLog::EndMessage;
445 
446         result = false;
447     }
448 
449     if (true != is_uni_atom_vertical_uniform_referenced && m_atomic_counters_supported)
450     {
451         m_testCtx.getLog()
452             << tcu::TestLog::Message
453             << "Wrong value of property GL_REFERENCED_BY_GEOMETRY_SHADER_EXT for GL_ATOMIC_COUNTER_BUFFER"
454             << tcu::TestLog::EndMessage;
455 
456         result = false;
457     }
458 
459     if (false != is_uni_atom_horizontal_uniform_referenced && m_atomic_counters_supported)
460     {
461         m_testCtx.getLog()
462             << tcu::TestLog::Message
463             << "Wrong value of property GL_REFERENCED_BY_GEOMETRY_SHADER_EXT for GL_ATOMIC_COUNTER_BUFFER"
464             << tcu::TestLog::EndMessage;
465 
466         result = false;
467     }
468 
469     if (true != is_storage_positions_shader_storage_block_referenced && m_ssbos_supported)
470     {
471         m_testCtx.getLog() << tcu::TestLog::Message
472                            << "Wrong value of property GL_REFERENCED_BY_GEOMETRY_SHADER_EXT for GL_SHADER_STORAGE_BLOCK"
473                            << tcu::TestLog::EndMessage;
474 
475         result = false;
476     }
477 
478     if (false != is_storage_ids_shader_storage_block_referenced && m_ssbos_supported)
479     {
480         m_testCtx.getLog() << tcu::TestLog::Message
481                            << "Wrong value of property GL_REFERENCED_BY_GEOMETRY_SHADER_EXT for GL_SHADER_STORAGE_BLOCK"
482                            << tcu::TestLog::EndMessage;
483 
484         result = false;
485     }
486 
487     if (true != is_positions_position_buffer_variable_referenced && m_ssbos_supported)
488     {
489         m_testCtx.getLog() << tcu::TestLog::Message
490                            << "Wrong value of property GL_REFERENCED_BY_GEOMETRY_SHADER_EXT for GL_BUFFER_VARIABLE"
491                            << tcu::TestLog::EndMessage;
492 
493         result = false;
494     }
495 
496     if (false != is_ids_ids_buffer_variable_referenced && m_ssbos_supported)
497     {
498         m_testCtx.getLog() << tcu::TestLog::Message
499                            << "Wrong value of property GL_REFERENCED_BY_GEOMETRY_SHADER_EXT for GL_BUFFER_VARIABLE"
500                            << tcu::TestLog::EndMessage;
501 
502         result = false;
503     }
504 
505     /* Verify results: properties that are not referenced */
506     if (false != is_uni_model_view_projection_uniform_referenced)
507     {
508         m_testCtx.getLog() << tcu::TestLog::Message
509                            << "Wrong value of property GL_REFERENCED_BY_GEOMETRY_SHADER_EXT for GL_UNIFORM"
510                            << tcu::TestLog::EndMessage;
511 
512         result = false;
513     }
514 
515     if (false != is_uni_matrices_uniform_referenced)
516     {
517         m_testCtx.getLog() << tcu::TestLog::Message
518                            << "Wrong value of property GL_REFERENCED_BY_GEOMETRY_SHADER_EXT for GL_UNIFORM_BLOCK"
519                            << tcu::TestLog::EndMessage;
520 
521         result = false;
522     }
523 
524     if (false != is_vs_in_position_program_input_referenced)
525     {
526         m_testCtx.getLog() << tcu::TestLog::Message
527                            << "Wrong value of property GL_REFERENCED_BY_GEOMETRY_SHADER_EXT for GL_PROGRAM_INPUT"
528                            << tcu::TestLog::EndMessage;
529 
530         result = false;
531     }
532 
533     if (false != is_vs_in_color_program_input_referenced)
534     {
535         m_testCtx.getLog() << tcu::TestLog::Message
536                            << "Wrong value of property GL_REFERENCED_BY_GEOMETRY_SHADER_EXT for GL_PROGRAM_INPUT"
537                            << tcu::TestLog::EndMessage;
538 
539         result = false;
540     }
541 
542     if (false != is_gl_fs_out_color_program_output_referenced)
543     {
544         m_testCtx.getLog() << tcu::TestLog::Message
545                            << "Wrong value of property GL_REFERENCED_BY_GEOMETRY_SHADER_EXT for GL_PROGRAM_OUTPUT"
546                            << tcu::TestLog::EndMessage;
547 
548         result = false;
549     }
550 
551     /* Set test result */
552     if (true == result)
553     {
554         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
555     }
556     else
557     {
558         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
559     }
560 
561     /* Done */
562     return STOP;
563 }
564 
565 /** Deinitializes GLES objects created during the test.
566  *
567  */
deinit()568 void GeometryShaderProgramResourceTest::deinit()
569 {
570     /* GL */
571     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
572 
573     /* Reset OpenGL ES state */
574     gl.useProgram(0);
575 
576     /* Delete program objects and shader objects */
577     if (m_program_object_id != 0)
578     {
579         gl.deleteProgram(m_program_object_id);
580     }
581 
582     if (m_vertex_shader_id != 0)
583     {
584         gl.deleteShader(m_vertex_shader_id);
585     }
586 
587     if (m_geometry_shader_id != 0)
588     {
589         gl.deleteShader(m_geometry_shader_id);
590     }
591 
592     if (m_fragment_shader_id != 0)
593     {
594         gl.deleteShader(m_fragment_shader_id);
595     }
596 
597     /* Release base class */
598     TestCaseBase::deinit();
599 }
600 
601 /** Queries property GL_REFERENCED_BY_GEOMETRY_SHADER_EXT for resource at specified index in specific interface.
602  *  Program object must be linked.
603  *
604  *  @param program_object_id Program which will be inspected;
605  *  @param interface         Queried interface;
606  *  @param index             Resource's index.
607  *
608  *  @return  true            Property value is 1
609  *           false           Property value is 0
610  **/
checkIfResourceAtIndexIsReferenced(glw::GLuint program_object_id,glw::GLenum interface,glw::GLuint index) const611 bool GeometryShaderProgramResourceTest::checkIfResourceAtIndexIsReferenced(glw::GLuint program_object_id,
612                                                                            glw::GLenum interface,
613                                                                            glw::GLuint index) const
614 {
615     (void)program_object_id;
616 
617     /* GL */
618     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
619 
620     /* Data for getProgramResourceiv */
621     glw::GLint params[] = {0};
622     glw::GLenum props[] = {m_glExtTokens.REFERENCED_BY_GEOMETRY_SHADER};
623 
624     /* Get property value */
625     gl.getProgramResourceiv(m_program_object_id, interface, index, 1, /* propCount */
626                             props, 1,                                 /* bufSize */
627                             0,                                        /* length */
628                             params);
629 
630     /**
631      *     The value one is written to <params> if an active
632      *     variable is referenced by the corresponding shader, or if an active
633      *     uniform block, shader storage block, or atomic counter buffer contains
634      *     at least one variable referenced by the corresponding shader.  Otherwise,
635      *     the value zero is written to <params>.
636      **/
637     if (1 == params[0])
638     {
639         return true;
640     }
641     else
642     {
643         return false;
644     }
645 }
646 
647 /** Queries property GL_REFERENCED_BY_GEOMETRY_SHADER_EXT for resource with specified name in specific interface.
648  *  Program object must be linked.
649  *
650  *  @param program_object_id Program which will be inspected
651  *  @param interface         Queried interface
652  *  @param name              Resource's name
653  *
654  *  @return  true            Property value is 1
655  *           false           Property value is 0, or resource is not available
656  **/
checkIfResourceIsReferenced(glw::GLuint program_object_id,glw::GLenum interface,const char * name) const657 bool GeometryShaderProgramResourceTest::checkIfResourceIsReferenced(glw::GLuint program_object_id,
658                                                                     glw::GLenum interface, const char *name) const
659 {
660     /* GL */
661     const glw::Functions &gl = m_context.getRenderContext().getFunctions();
662 
663     /* Resource index */
664     glw::GLuint index = GL_INVALID_INDEX;
665 
666     /* Get resource's index by name */
667     index = gl.getProgramResourceIndex(program_object_id, interface, name);
668 
669     /**
670      *     Otherwise, <name> is considered not to be the name
671      *     of an active resource, and INVALID_INDEX is returned.
672      **/
673     if (GL_INVALID_INDEX == index)
674     {
675         return false;
676     }
677 
678     /* Get property by index */
679     return checkIfResourceAtIndexIsReferenced(program_object_id, interface, index);
680 }
681 
682 } // namespace glcts
683