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