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