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 } /* glcts */
683