• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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