Home | History | Annotate | Download | only in geometry_shader
      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  **/
    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  **/
    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  **/
    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  */
    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