Home | History | Annotate | Download | only in gl
      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 /**
     25  * \file  gl3cTransformFeedbackOverflowQueryTests.cpp
     26  * \brief Implements conformance tests for "Transform Feedback Overflow
     27  *        Query" functionality.
     28  */ /*-------------------------------------------------------------------*/
     29 
     30 #include "gl3cTransformFeedbackOverflowQueryTests.hpp"
     31 
     32 #include "deMath.h"
     33 #include "deSharedPtr.hpp"
     34 
     35 #include "gluContextInfo.hpp"
     36 #include "gluDefs.hpp"
     37 #include "gluPixelTransfer.hpp"
     38 #include "gluShaderProgram.hpp"
     39 
     40 #include "tcuFuzzyImageCompare.hpp"
     41 #include "tcuImageCompare.hpp"
     42 #include "tcuRenderTarget.hpp"
     43 #include "tcuSurface.hpp"
     44 #include "tcuTestLog.hpp"
     45 
     46 #include "glw.h"
     47 #include "glwFunctions.hpp"
     48 
     49 namespace gl3cts
     50 {
     51 
     52 /*
     53  Base class of all test cases of the feature. Enforces the requirements below:
     54 
     55  * Check that the extension string is available.
     56  */
     57 class TransformFeedbackOverflowQueryBaseTest : public deqp::TestCase
     58 {
     59 protected:
     60 	TransformFeedbackOverflowQueryBaseTest(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api,
     61 										   const char* name, const char* description)
     62 		: TestCase(context, name, description), m_api(api), m_max_vertex_streams(0)
     63 	{
     64 	}
     65 
     66 	/* Checks whether the feature is supported. */
     67 	bool featureSupported()
     68 	{
     69 		if (m_api == TransformFeedbackOverflowQueryTests::API_GL_ARB_transform_feedback_overflow_query)
     70 		{
     71 			glu::ContextType contextType = m_context.getRenderContext().getType();
     72 			if (m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback_overflow_query") ||
     73 				glu::contextSupports(contextType, glu::ApiType::core(4, 6)))
     74 			{
     75 				return true;
     76 			}
     77 		}
     78 		return false;
     79 	}
     80 
     81 	/* Checks whether transform_feedback2 is supported. */
     82 	bool supportsTransformFeedback2()
     83 	{
     84 		return (m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback2") ||
     85 				glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType(4, 0, glu::PROFILE_CORE)));
     86 	}
     87 
     88 	/* Checks whether transform_feedback3 is supported. */
     89 	bool supportsTransformFeedback3()
     90 	{
     91 		return (m_context.getContextInfo().isExtensionSupported("GL_ARB_transform_feedback3") ||
     92 				glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType(4, 0, glu::PROFILE_CORE)));
     93 	}
     94 
     95 	/* Checks whether gpu_shader5 is supported. */
     96 	bool supportsGpuShader5()
     97 	{
     98 		return (m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader5") ||
     99 				glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType(4, 0, glu::PROFILE_CORE)));
    100 	}
    101 
    102 	/* Checks whether conditional_render_inverted is supported. */
    103 	bool supportsConditionalRenderInverted()
    104 	{
    105 		return (m_context.getContextInfo().isExtensionSupported("GL_ARB_conditional_render_inverted") ||
    106 				glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType(4, 5, glu::PROFILE_CORE)));
    107 	}
    108 
    109 	/* Checks whether query_buffer_object are supported. */
    110 	bool supportsQueryBufferObject()
    111 	{
    112 		return (m_context.getContextInfo().isExtensionSupported("GL_ARB_query_buffer_object") ||
    113 				glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType(4, 4, glu::PROFILE_CORE)));
    114 	}
    115 
    116 	/* Returns the maximum number of vertex streams. */
    117 	GLuint getMaxVertexStreams() const
    118 	{
    119 		return m_max_vertex_streams;
    120 	}
    121 
    122 	/* Basic test init, child classes must call it. */
    123 	virtual void init()
    124 	{
    125 		if (!featureSupported())
    126 		{
    127 			throw tcu::NotSupportedError("Required transform_feedback_overflow_query extension is not supported");
    128 		}
    129 
    130 		if (supportsTransformFeedback3())
    131 		{
    132 			m_max_vertex_streams = (GLuint)m_context.getContextInfo().getInt(GL_MAX_VERTEX_STREAMS);
    133 		}
    134 	}
    135 
    136 protected:
    137 	const TransformFeedbackOverflowQueryTests::API m_api;
    138 
    139 private:
    140 	GLuint m_max_vertex_streams;
    141 };
    142 
    143 /*
    144  API Implementation Dependent State Test
    145 
    146  * Check that calling GetQueryiv with target TRANSFORM_FEEDBACK_OVERFLOW
    147  and pname QUERY_COUNTER_BITS returns a non-negative value without error.
    148 
    149  * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling
    150  GetQueryiv with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW and pname
    151  QUERY_COUNTER_BITS returns a non-negative value without error.
    152  */
    153 class TransformFeedbackOverflowQueryImplDepState : public TransformFeedbackOverflowQueryBaseTest
    154 {
    155 public:
    156 	TransformFeedbackOverflowQueryImplDepState(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api,
    157 											   const char* name)
    158 		: TransformFeedbackOverflowQueryBaseTest(
    159 			  context, api, name,
    160 			  "Tests whether the implementation dependent state defined by the feature matches the requirements.")
    161 	{
    162 	}
    163 
    164 	/* Test case iterate function. Contains the actual test case logic. */
    165 	IterateResult iterate()
    166 	{
    167 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    168 		GLint				  counterBits;
    169 
    170 		gl.getQueryiv(GL_TRANSFORM_FEEDBACK_OVERFLOW, GL_QUERY_COUNTER_BITS, &counterBits);
    171 		if (counterBits < 0)
    172 		{
    173 			TCU_FAIL("Value of QUERY_COUNTER_BITS for query target TRANSFORM_FEEDBACK_OVERFLOW is invalid");
    174 		}
    175 
    176 		if (supportsTransformFeedback3())
    177 		{
    178 			gl.getQueryiv(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, GL_QUERY_COUNTER_BITS, &counterBits);
    179 			if (counterBits < 0)
    180 			{
    181 				TCU_FAIL("Value of QUERY_COUNTER_BITS for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW is invalid");
    182 			}
    183 		}
    184 
    185 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    186 
    187 		return STOP;
    188 	}
    189 };
    190 
    191 /*
    192  Base class for all test cases of the feature that verify newly introduced context state.
    193  */
    194 class TransformFeedbackOverflowQueryContextStateBase : public TransformFeedbackOverflowQueryBaseTest
    195 {
    196 protected:
    197 	TransformFeedbackOverflowQueryContextStateBase(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api,
    198 												   const char* name, const char* description)
    199 		: TransformFeedbackOverflowQueryBaseTest(context, api, name, description)
    200 	{
    201 	}
    202 
    203 	/* Returns whether CURRENT_QUERY state for the specified target and index matches the given value. */
    204 	bool verifyCurrentQueryState(GLenum target, GLuint index, GLuint value)
    205 	{
    206 		const glw::Functions& gl	   = m_context.getRenderContext().getFunctions();
    207 		GLint				  expected = (GLint)value;
    208 		GLint				  actual;
    209 
    210 		// Use GetQueryIndexediv by default
    211 		gl.getQueryIndexediv(target, index, GL_CURRENT_QUERY, &actual);
    212 		if (actual != expected)
    213 		{
    214 			return false;
    215 		}
    216 
    217 		if (index == 0)
    218 		{
    219 			// If index is zero then GetQueryiv should also return the expected value
    220 			gl.getQueryiv(target, GL_CURRENT_QUERY, &actual);
    221 			if (actual != expected)
    222 			{
    223 				return false;
    224 			}
    225 		}
    226 
    227 		return true;
    228 	}
    229 };
    230 
    231 /*
    232  API Default Context State Test
    233 
    234  * Check that calling GetQueryiv with target TRANSFORM_FEEDBACK_OVERFLOW
    235  and pname CURRENT_QUERY returns zero by default.
    236 
    237  * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling
    238  GetQueryIndexediv with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW and
    239  pname CURRENT_QUERY returns zero for any index between zero and MAX_-
    240  VERTEX_STREAMS.
    241  */
    242 class TransformFeedbackOverflowQueryDefaultState : public TransformFeedbackOverflowQueryContextStateBase
    243 {
    244 public:
    245 	TransformFeedbackOverflowQueryDefaultState(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api,
    246 											   const char* name)
    247 		: TransformFeedbackOverflowQueryContextStateBase(
    248 			  context, api, name,
    249 			  "Tests whether the new context state defined by the feature has the expected default values.")
    250 	{
    251 	}
    252 
    253 	/* Test case iterate function. Contains the actual test case logic. */
    254 	IterateResult iterate()
    255 	{
    256 		if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, 0))
    257 		{
    258 			TCU_FAIL("Default value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_OVERFLOW is non-zero");
    259 		}
    260 
    261 		if (supportsTransformFeedback3())
    262 		{
    263 			for (GLuint i = 0; i < getMaxVertexStreams(); ++i)
    264 			{
    265 				if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, 0, 0))
    266 				{
    267 					TCU_FAIL("Default value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW "
    268 							 "is non-zero");
    269 				}
    270 			}
    271 		}
    272 
    273 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    274 
    275 		return STOP;
    276 	}
    277 };
    278 
    279 /*
    280  API Context State Update Test
    281 
    282  * Check that after a successful call to BeginQuery with target TRANSFORM_-
    283  FEEDBACK_OVERFLOW_ARB calling GetQueryiv with the same target and with
    284  pname CURRENT_QUERY returns the name of the query previously passed to
    285  BeginQuery. Also check that after calling EndQuery with the same target
    286  GetQueryiv returns zero for the same parameters.
    287 
    288  * If GL 4.0 or ARB_transform_feedback3 is supported, check that after a
    289  successful call to BeginQueryIndexed with target TRANSFORM_FEEDBACK_-
    290  STREAM_OVERFLOW_ARB calling GetQueryIndexediv with the same target and
    291  with pname CURRENT_QUERY returns the name of the query previously passed
    292  to BeginQueryIndexed if the index parameters match and otherwise it
    293  returns zero. Also check that after calling EndQueryIndexed with the
    294  same target and index GetQueryIndexediv returns zero for the same
    295  parameters for all indices. Indices used should be between zero and
    296  MAX_VERTEX_STREAMS.
    297  */
    298 class TransformFeedbackOverflowQueryStateUpdate : public TransformFeedbackOverflowQueryContextStateBase
    299 {
    300 public:
    301 	TransformFeedbackOverflowQueryStateUpdate(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api,
    302 											  const char* name)
    303 		: TransformFeedbackOverflowQueryContextStateBase(
    304 			  context, api, name,
    305 			  "Tests whether the new context state defined by the feature is correctly updated after a successful "
    306 			  "call to {Begin|End}Query[Indexed] if the target of the query is one of the newly introduced ones.")
    307 		, m_overflow_query(0)
    308 		, m_stream_overflow_query(0)
    309 	{
    310 	}
    311 
    312 	/* Test case init. */
    313 	virtual void init()
    314 	{
    315 		TransformFeedbackOverflowQueryContextStateBase::init();
    316 
    317 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    318 
    319 		gl.genQueries(1, &m_overflow_query);
    320 		gl.genQueries(1, &m_stream_overflow_query);
    321 	}
    322 
    323 	/* Test case deinit */
    324 	virtual void deinit()
    325 	{
    326 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    327 
    328 		gl.deleteQueries(1, &m_overflow_query);
    329 		gl.deleteQueries(1, &m_stream_overflow_query);
    330 
    331 		TransformFeedbackOverflowQueryContextStateBase::deinit();
    332 	}
    333 
    334 	/* Test case iterate function. Contains the actual test case logic. */
    335 	IterateResult iterate()
    336 	{
    337 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    338 
    339 		// Call BeginQuery
    340 		gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_overflow_query);
    341 
    342 		// Verify that CURRENT_QUERY is set to the name of the query
    343 		if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, m_overflow_query))
    344 		{
    345 			TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_OVERFLOW is not updated properly "
    346 					 "after a call to BeginQuery");
    347 		}
    348 
    349 		// Call EndQuery
    350 		gl.endQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW);
    351 
    352 		// Verify that CURRENT_QUERY is reset to zero
    353 		if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, 0))
    354 		{
    355 			TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_OVERFLOW is not reset properly "
    356 					 "after a call to EndQuery");
    357 		}
    358 
    359 		if (supportsTransformFeedback3())
    360 		{
    361 			for (GLuint i = 0; i < getMaxVertexStreams(); ++i)
    362 			{
    363 				// Call BeginQueryIndexed with specified index
    364 				gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i, m_stream_overflow_query);
    365 
    366 				// Verify that CURRENT_QUERY is set to the name of the query for the specified index, but remains zero for other indices
    367 				for (GLuint j = 0; j < getMaxVertexStreams(); ++j)
    368 				{
    369 					if (i == j)
    370 					{
    371 						if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, j, m_stream_overflow_query))
    372 						{
    373 							TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW "
    374 									 "is not updated properly after a call to BeginQueryIndexed");
    375 						}
    376 					}
    377 					else
    378 					{
    379 						if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, j, 0))
    380 						{
    381 							TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW "
    382 									 "is incorrectly updated for an unrelated vertex stream"
    383 									 "index after a call to BeginQueryIndexed");
    384 						}
    385 					}
    386 				}
    387 
    388 				// Call EndQueryIndexed with specified index
    389 				gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i);
    390 
    391 				// Verify that CURRENT_QUERY is reset to zero for the specified index and still remains zero for other indices
    392 				for (GLuint j = 0; j < getMaxVertexStreams(); ++j)
    393 				{
    394 					if (i == j)
    395 					{
    396 						if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, j, 0))
    397 						{
    398 							TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW "
    399 									 "is not reset properly after a call to EndQueryIndexed");
    400 						}
    401 					}
    402 					else
    403 					{
    404 						if (!verifyCurrentQueryState(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, j, 0))
    405 						{
    406 							TCU_FAIL("Value of CURRENT_QUERY for query target TRANSFORM_FEEDBACK_STREAM_OVERFLOW "
    407 									 "is incorrectly updated for an unrelated vertex stream"
    408 									 "index after a call to EndQueryIndexed");
    409 						}
    410 					}
    411 				}
    412 			}
    413 		}
    414 
    415 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    416 
    417 		return STOP;
    418 	}
    419 
    420 protected:
    421 	GLuint m_overflow_query;
    422 	GLuint m_stream_overflow_query;
    423 };
    424 
    425 /*
    426  Base class for all test cases of the feature that verify various error scenarios.
    427  */
    428 class TransformFeedbackOverflowQueryErrorBase : public TransformFeedbackOverflowQueryBaseTest
    429 {
    430 protected:
    431 	TransformFeedbackOverflowQueryErrorBase(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api,
    432 											const char* name, const char* description)
    433 		: TransformFeedbackOverflowQueryBaseTest(context, api, name, description), m_case_name(0)
    434 	{
    435 	}
    436 
    437 	/* Starts a new error scenario sub-test with the given name. The name is used in error messages if the sub-test fails. */
    438 	void startTest(const char* caseName)
    439 	{
    440 		m_case_name = caseName;
    441 	}
    442 
    443 	/* Verifies whether the actually generated error matches that of the expected one. If not then it triggers the failure
    444 	 of the test case with the sub-case name used as the failure message. */
    445 	void verifyError(GLenum expectedError)
    446 	{
    447 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    448 
    449 		GLenum actualError = gl.getError();
    450 
    451 		if (actualError != expectedError)
    452 		{
    453 			TCU_FAIL(m_case_name);
    454 		}
    455 	}
    456 
    457 private:
    458 	const char* m_case_name;
    459 };
    460 
    461 /*
    462  API Invalid Index Error Test
    463 
    464  * Check that calling GetQueryIndexediv with target TRANSFORM_FEEDBACK_-
    465  OVERFLOW_ARB and a non-zero index generates an INVALID_VALUE error.
    466 
    467  * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling
    468  GetQueryIndexediv with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW
    469  and an index greater than or equal to MAX_VERTEX_STREAMS generates an
    470  INVALID_VALUE error.
    471 
    472  * Check that calling BeginQueryIndexed with target TRANSFORM_FEEDBACK_-
    473  OVERFLOW_ARB and a non-zero index generates an INVALID_VALUE error.
    474 
    475  * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling
    476  BeginQueryIndexed with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW
    477  and an index greater than or equal to MAX_VERTEX_STREAMS generates an
    478  INVALID_VALUE error.
    479  */
    480 class TransformFeedbackOverflowQueryErrorInvalidIndex : public TransformFeedbackOverflowQueryErrorBase
    481 {
    482 public:
    483 	TransformFeedbackOverflowQueryErrorInvalidIndex(deqp::Context&							 context,
    484 													TransformFeedbackOverflowQueryTests::API api, const char* name)
    485 		: TransformFeedbackOverflowQueryErrorBase(
    486 			  context, api, name, "Verifies whether an INVALID_VALUE error is properly generated if GetQueryIndexediv "
    487 								  "or BeginQueryIndexed is called "
    488 								  "with an invalid index when using the new targets introduced by the feature.")
    489 		, m_query(0)
    490 	{
    491 	}
    492 
    493 	/* Test case init. */
    494 	virtual void init()
    495 	{
    496 		TransformFeedbackOverflowQueryErrorBase::init();
    497 
    498 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    499 
    500 		gl.genQueries(1, &m_query);
    501 	}
    502 
    503 	/* Test case deinit */
    504 	virtual void deinit()
    505 	{
    506 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    507 
    508 		gl.deleteQueries(1, &m_query);
    509 
    510 		TransformFeedbackOverflowQueryErrorBase::deinit();
    511 	}
    512 
    513 	/* Test case iterate function. Contains the actual test case logic. */
    514 	IterateResult iterate()
    515 	{
    516 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    517 		GLint				  value;
    518 
    519 		startTest("GetQueryIndexediv must generate INVALID_VALUE if <target> is "
    520 				  "TRANSFORM_FEEDBACK_OVERFLOW and <index> is non-zero.");
    521 
    522 		for (GLuint i = 1; i < getMaxVertexStreams(); ++i)
    523 		{
    524 			gl.getQueryIndexediv(GL_TRANSFORM_FEEDBACK_OVERFLOW, i, GL_CURRENT_QUERY, &value);
    525 			verifyError(GL_INVALID_VALUE);
    526 		}
    527 
    528 		if (supportsTransformFeedback3())
    529 		{
    530 			startTest("GetQueryIndexediv must generate INVALID_VALUE if <target> is "
    531 					  "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and <index> is greater "
    532 					  "than or equal to MAX_VERTEX_STREAMS.");
    533 
    534 			for (GLuint i = getMaxVertexStreams(); i < getMaxVertexStreams() + 4; ++i)
    535 			{
    536 				gl.getQueryIndexediv(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i, GL_CURRENT_QUERY, &value);
    537 				verifyError(GL_INVALID_VALUE);
    538 			}
    539 		}
    540 
    541 		startTest("BeginQueryIndexed must generate INVALID_VALUE if <target> is "
    542 				  "TRANSFORM_FEEDBACK_OVERFLOW and <index> is non-zero.");
    543 
    544 		for (GLuint i = 1; i < getMaxVertexStreams(); ++i)
    545 		{
    546 			gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_OVERFLOW, i, m_query);
    547 			verifyError(GL_INVALID_VALUE);
    548 		}
    549 
    550 		if (supportsTransformFeedback3())
    551 		{
    552 			startTest("BeginQueryIndexed must generate INVALID_VALUE if <target> is "
    553 					  "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and <index> is greater "
    554 					  "than or equal to MAX_VERTEX_STREAMS.");
    555 
    556 			for (GLuint i = getMaxVertexStreams(); i < getMaxVertexStreams() + 4; ++i)
    557 			{
    558 				gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i, m_query);
    559 				verifyError(GL_INVALID_VALUE);
    560 			}
    561 		}
    562 
    563 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    564 
    565 		return STOP;
    566 	}
    567 
    568 protected:
    569 	GLuint m_query;
    570 };
    571 
    572 /*
    573  API Already Active Error Test
    574 
    575  * Check that calling BeginQuery with target TRANSFORM_FEEDBACK_OVERFLOW
    576  generates an INVALID_OPERATION error if there is already an active
    577  query for TRANSFORM_FEEDBACK_OVERFLOW.
    578 
    579  * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling
    580  BeginQueryIndexed with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW
    581  generates an INVALID_OPERATION error if there is already an active
    582  query for TRANSFORM_FEEDBACK_STREAM_OVERFLOW for the specified
    583  index.
    584 
    585  * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling
    586  BeginQueryIndexed with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW
    587  generates an INVALID_OPERATION error if the specified query is already
    588  active on another TRANSFORM_FEEDBACK_STREAM_OVERFLOW target with
    589  a different index.
    590  */
    591 class TransformFeedbackOverflowQueryErrorAlreadyActive : public TransformFeedbackOverflowQueryErrorBase
    592 {
    593 public:
    594 	TransformFeedbackOverflowQueryErrorAlreadyActive(deqp::Context&							  context,
    595 													 TransformFeedbackOverflowQueryTests::API api, const char* name)
    596 		: TransformFeedbackOverflowQueryErrorBase(context, api, name,
    597 												  "Verifies whether an INVALID_OPERATION error is properly generated "
    598 												  "if BeginQuery[Indexed] is used to try to start "
    599 												  "a query on an index that has already a query active, or the query "
    600 												  "object itself is active on another index.")
    601 		, m_query(0)
    602 		, m_active_overflow_query(0)
    603 		, m_active_stream_overflow_query(0)
    604 		, m_active_query_stream_index(0)
    605 	{
    606 	}
    607 
    608 	/* Test case init. */
    609 	virtual void init()
    610 	{
    611 		TransformFeedbackOverflowQueryErrorBase::init();
    612 
    613 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    614 
    615 		gl.genQueries(1, &m_query);
    616 
    617 		gl.genQueries(1, &m_active_overflow_query);
    618 		gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_active_overflow_query);
    619 
    620 		if (supportsTransformFeedback3())
    621 		{
    622 			gl.genQueries(1, &m_active_stream_overflow_query);
    623 			m_active_query_stream_index = 2;
    624 			gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_query_stream_index,
    625 								 m_active_stream_overflow_query);
    626 		}
    627 	}
    628 
    629 	/* Test case deinit */
    630 	virtual void deinit()
    631 	{
    632 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    633 
    634 		if (supportsTransformFeedback3())
    635 		{
    636 			gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_query_stream_index);
    637 			gl.deleteQueries(1, &m_active_stream_overflow_query);
    638 		}
    639 
    640 		gl.endQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW);
    641 		gl.deleteQueries(1, &m_active_overflow_query);
    642 
    643 		gl.deleteQueries(1, &m_query);
    644 
    645 		TransformFeedbackOverflowQueryErrorBase::deinit();
    646 	}
    647 
    648 	/* Test case iterate function. Contains the actual test case logic. */
    649 	IterateResult iterate()
    650 	{
    651 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    652 
    653 		startTest("BeginQuery[Indexed] must generate INVALID_OPERATION if <target> is "
    654 				  "TRANSFORM_FEEDBACK_OVERFLOW and there is already an active "
    655 				  "query for TRANSFORM_FEEDBACK_ARB.");
    656 
    657 		gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_query);
    658 		verifyError(GL_INVALID_OPERATION);
    659 		gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, m_query);
    660 		verifyError(GL_INVALID_OPERATION);
    661 
    662 		if (supportsTransformFeedback3())
    663 		{
    664 			startTest("BeginQueryIndexed must generate INVALID_OPERATION if <target> is "
    665 					  "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and there is already an active "
    666 					  "query for TRANSFORM_FEEDBACK_STREAM_OVERFLOW for the specified index.");
    667 
    668 			gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_query_stream_index, m_query);
    669 			verifyError(GL_INVALID_OPERATION);
    670 
    671 			startTest("BeginQuery[Indexed] must generate INVALID_OPERATION if <target> is "
    672 					  "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and the specified query is "
    673 					  "already active on another TRANSFORM_FEEDBACK_STREAM_OVERFLOW "
    674 					  "target with a different index.");
    675 
    676 			for (GLuint i = 0; i < getMaxVertexStreams(); ++i)
    677 			{
    678 				if (i != m_active_query_stream_index)
    679 				{
    680 					gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i, m_active_stream_overflow_query);
    681 					verifyError(GL_INVALID_OPERATION);
    682 
    683 					if (i == 0)
    684 					{
    685 						gl.beginQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_stream_overflow_query);
    686 						verifyError(GL_INVALID_OPERATION);
    687 					}
    688 				}
    689 			}
    690 		}
    691 
    692 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    693 
    694 		return STOP;
    695 	}
    696 
    697 protected:
    698 	GLuint m_query;
    699 	GLuint m_active_overflow_query;
    700 	GLuint m_active_stream_overflow_query;
    701 	GLuint m_active_query_stream_index;
    702 };
    703 
    704 /*
    705  API Incompatible Target Error Test
    706 
    707  * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling
    708  BeginQueryIndexed with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW
    709  generates an INVALID_OPERATION error if the specified query was
    710  previously used as a TRANSFORM_FEEDBACK_OVERFLOW query. Also check
    711  the other way around.
    712  */
    713 class TransformFeedbackOverflowQueryErrorIncompatibleTarget : public TransformFeedbackOverflowQueryErrorBase
    714 {
    715 public:
    716 	TransformFeedbackOverflowQueryErrorIncompatibleTarget(deqp::Context&						   context,
    717 														  TransformFeedbackOverflowQueryTests::API api,
    718 														  const char*							   name)
    719 		: TransformFeedbackOverflowQueryErrorBase(context, api, name,
    720 												  "Verifies whether an INVALID_OPERATION error is properly generated "
    721 												  "if BeginQuery[Indexed] is called with one of "
    722 												  "the newly introduced query targets but one that is different than "
    723 												  "that used earlier on the same query object.")
    724 		, m_overflow_query(0)
    725 		, m_stream_overflow_query(0)
    726 		, m_incompatible_query(0)
    727 	{
    728 	}
    729 
    730 	/* Test case init. */
    731 	virtual void init()
    732 	{
    733 		TransformFeedbackOverflowQueryErrorBase::init();
    734 
    735 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    736 
    737 		gl.genQueries(1, &m_incompatible_query);
    738 		gl.beginQuery(GL_SAMPLES_PASSED, m_incompatible_query);
    739 		gl.endQuery(GL_SAMPLES_PASSED);
    740 
    741 		gl.genQueries(1, &m_overflow_query);
    742 		gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_overflow_query);
    743 		gl.endQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW);
    744 
    745 		if (supportsTransformFeedback3())
    746 		{
    747 			gl.genQueries(1, &m_stream_overflow_query);
    748 			gl.beginQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_stream_overflow_query);
    749 			gl.endQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW);
    750 		}
    751 	}
    752 
    753 	/* Test case deinit */
    754 	virtual void deinit()
    755 	{
    756 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    757 
    758 		gl.deleteQueries(1, &m_incompatible_query);
    759 
    760 		gl.deleteQueries(1, &m_overflow_query);
    761 
    762 		if (supportsTransformFeedback3())
    763 		{
    764 			gl.deleteQueries(1, &m_stream_overflow_query);
    765 		}
    766 
    767 		TransformFeedbackOverflowQueryErrorBase::deinit();
    768 	}
    769 
    770 	/* Test case iterate function. Contains the actual test case logic. */
    771 	IterateResult iterate()
    772 	{
    773 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    774 
    775 		startTest("BeginQuery[Indexed] must generate INVALID_OPERATION if <target> is "
    776 				  "TRANSFORM_FEEDBACK_OVERFLOW and the specified query was "
    777 				  "previously used with another target.");
    778 
    779 		gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_incompatible_query);
    780 		verifyError(GL_INVALID_OPERATION);
    781 		gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, m_incompatible_query);
    782 		verifyError(GL_INVALID_OPERATION);
    783 
    784 		if (supportsTransformFeedback3())
    785 		{
    786 			gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_stream_overflow_query);
    787 			verifyError(GL_INVALID_OPERATION);
    788 			gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0, m_stream_overflow_query);
    789 			verifyError(GL_INVALID_OPERATION);
    790 
    791 			startTest("BeginQuery[Indexed] must generate INVALID_OPERATION if <target> is "
    792 					  "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and the specified query "
    793 					  "was previously used with another target.");
    794 
    795 			gl.beginQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_incompatible_query);
    796 			verifyError(GL_INVALID_OPERATION);
    797 			gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, 2, m_incompatible_query);
    798 			verifyError(GL_INVALID_OPERATION);
    799 
    800 			gl.beginQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_overflow_query);
    801 			verifyError(GL_INVALID_OPERATION);
    802 			gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, 2, m_overflow_query);
    803 			verifyError(GL_INVALID_OPERATION);
    804 		}
    805 
    806 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    807 
    808 		return STOP;
    809 	}
    810 
    811 protected:
    812 	GLuint m_overflow_query;
    813 	GLuint m_stream_overflow_query;
    814 	GLuint m_incompatible_query;
    815 };
    816 
    817 /*
    818  API No Query Active Error Test
    819 
    820  * Check that calling EndQuery with target TRANSFORM_FEEDBACK_OVERFLOW
    821  generates an INVALID_OPERATION error if no query is active for
    822  TRANSFORM_FEEDBACK_OVERFLOW.
    823 
    824  * If GL 4.0 or ARB_transform_feedback3 is supported, check that calling
    825  EndQueryIndexed with target TRANSFORM_FEEDBACK_STREAM_OVERFLOW
    826  generates an INVALID_OPERATION error if no query is active for
    827  TRANSFORM_FEEDBACK_STREAM_OVERFLOW for the specified index, even
    828  if there is an active query for another index.
    829  */
    830 class TransformFeedbackOverflowQueryErrorNoActiveQuery : public TransformFeedbackOverflowQueryErrorBase
    831 {
    832 public:
    833 	TransformFeedbackOverflowQueryErrorNoActiveQuery(deqp::Context&							  context,
    834 													 TransformFeedbackOverflowQueryTests::API api, const char* name)
    835 		: TransformFeedbackOverflowQueryErrorBase(context, api, name,
    836 												  "Verifies whether an INVALID_OPERATION error is properly generated "
    837 												  "if EndQuery[Indexed] is called with a target "
    838 												  "(and index) for which there isn't a currently active query.")
    839 		, m_active_stream_overflow_query(0)
    840 		, m_active_query_stream_index(0)
    841 	{
    842 	}
    843 
    844 	/* Test case init. */
    845 	virtual void init()
    846 	{
    847 		TransformFeedbackOverflowQueryErrorBase::init();
    848 
    849 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    850 
    851 		if (supportsTransformFeedback3())
    852 		{
    853 			gl.genQueries(1, &m_active_stream_overflow_query);
    854 			m_active_query_stream_index = 2;
    855 			gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_query_stream_index,
    856 								 m_active_stream_overflow_query);
    857 		}
    858 	}
    859 
    860 	/* Test case deinit */
    861 	virtual void deinit()
    862 	{
    863 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    864 
    865 		if (supportsTransformFeedback3())
    866 		{
    867 			gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, m_active_query_stream_index);
    868 			gl.deleteQueries(1, &m_active_stream_overflow_query);
    869 		}
    870 
    871 		TransformFeedbackOverflowQueryErrorBase::deinit();
    872 	}
    873 
    874 	/* Test case iterate function. Contains the actual test case logic. */
    875 	IterateResult iterate()
    876 	{
    877 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    878 
    879 		startTest("EndQuery[Indexed] must generate INVALID_OPERATION if <target> is "
    880 				  "TRANSFORM_FEEDBACK_OVERFLOW and there is no query active "
    881 				  "for TRANSFORM_FEEDBACK_OVERFLOW.");
    882 
    883 		gl.endQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW);
    884 		verifyError(GL_INVALID_OPERATION);
    885 		gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_OVERFLOW, 0);
    886 		verifyError(GL_INVALID_OPERATION);
    887 
    888 		if (supportsTransformFeedback3())
    889 		{
    890 			startTest("EndQuery[Indexed] must generate INVALID_OPERATION if <target> is "
    891 					  "TRANSFORM_FEEDBACK_STREAM_OVERFLOW and there is no query active "
    892 					  "for TRANSFORM_FEEDBACK_STREAM_OVERFLOW for the given index.");
    893 
    894 			for (GLuint i = 0; i < getMaxVertexStreams(); ++i)
    895 			{
    896 				if (i != m_active_query_stream_index)
    897 				{
    898 					gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i);
    899 					verifyError(GL_INVALID_OPERATION);
    900 
    901 					if (i == 0)
    902 					{
    903 						gl.endQuery(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW);
    904 						verifyError(GL_INVALID_OPERATION);
    905 					}
    906 				}
    907 			}
    908 		}
    909 
    910 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    911 
    912 		return STOP;
    913 	}
    914 
    915 protected:
    916 	GLuint m_active_stream_overflow_query;
    917 	GLuint m_active_query_stream_index;
    918 };
    919 
    920 /*
    921  Base class of all functionality tests. Helps enforce the following requirements:
    922 
    923  * Ensuring that QUERY_COUNTER_BITS is at least one for the TRANSFORM_FEEDBACK_OVERFLOW query
    924  target before running any test that uses such a query's result.
    925 
    926  * Ensuring that GL 4.0 or ARB_transform_feedback3 is supported and QUERY_COUNTER_BITS is at least
    927  one for the TRANSFORM_FEEDBACK_STREAM_OVERFLOW query target before running any test that
    928  uses such a query's result.
    929  */
    930 class TransformFeedbackOverflowQueryFunctionalBase : public TransformFeedbackOverflowQueryBaseTest
    931 {
    932 protected:
    933 	TransformFeedbackOverflowQueryFunctionalBase(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api,
    934 												 const char* name, const char* description)
    935 		: TransformFeedbackOverflowQueryBaseTest(context, api, name, description)
    936 		, m_overflow_query(0)
    937 		, m_stream_overflow_query(NULL)
    938 		, m_query_buffer(0)
    939 		, m_tf_buffer_count(0)
    940 		, m_tf_buffer(NULL)
    941 		, m_vao(0)
    942 		, m_program(0)
    943 		, m_checker_program(NULL)
    944 	{
    945 	}
    946 
    947 	/* Tells whether functional tests using TRANSFORM_FEEDBACK_OVERFLOW are runnable */
    948 	bool canTestOverflow()
    949 	{
    950 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    951 		GLint				  counterBits;
    952 
    953 		gl.getQueryiv(GL_TRANSFORM_FEEDBACK_OVERFLOW, GL_QUERY_COUNTER_BITS, &counterBits);
    954 
    955 		return counterBits > 0;
    956 	}
    957 
    958 	/* Tells whether functional tests using TRANSFORM_FEEDBACK_STREAM_OVERFLOW are runnable */
    959 	bool canTestStreamOverflow()
    960 	{
    961 		if (supportsTransformFeedback3())
    962 		{
    963 			const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    964 			GLint				  counterBits;
    965 
    966 			gl.getQueryiv(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, GL_QUERY_COUNTER_BITS, &counterBits);
    967 
    968 			return counterBits > 0;
    969 		}
    970 		else
    971 		{
    972 			return false;
    973 		}
    974 	}
    975 
    976 	/* Dummy vertex shader. */
    977 	const char* dummyVsh()
    978 	{
    979 		return "#version 150 core\n"
    980 			   "void main() {\n"
    981 			   "    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n"
    982 			   "}\n";
    983 	}
    984 
    985 	/* Dummy fragment shader */
    986 	const char* dummyFsh()
    987 	{
    988 		return "#version 150 core\n"
    989 			   "void main() {}\n";
    990 	}
    991 
    992 	/* Functional test init. Creates necessary query objects. */
    993 	virtual void init()
    994 	{
    995 		TransformFeedbackOverflowQueryBaseTest::init();
    996 
    997 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    998 
    999 		if (canTestOverflow())
   1000 		{
   1001 			// Setup vertex array
   1002 			gl.genVertexArrays(1, &m_vao);
   1003 			gl.bindVertexArray(m_vao);
   1004 
   1005 			// Setup queries
   1006 			gl.genQueries(1, &m_overflow_query);
   1007 
   1008 			if (canTestStreamOverflow())
   1009 			{
   1010 				m_stream_overflow_query = new GLuint[getMaxVertexStreams()];
   1011 
   1012 				gl.genQueries(getMaxVertexStreams(), m_stream_overflow_query);
   1013 			}
   1014 
   1015 			// Setup checker program
   1016 			m_checker_program =
   1017 				new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(dummyVsh(), dummyFsh()));
   1018 			if (!m_checker_program->isOk())
   1019 			{
   1020 				TCU_FAIL("Checker program compilation failed");
   1021 			}
   1022 
   1023 			// Setup transform feedback shader and buffers
   1024 			buildTransformFeedbackProgram();
   1025 			setupTransformFeedbackBuffers();
   1026 		}
   1027 		else
   1028 		{
   1029 			throw tcu::NotSupportedError(
   1030 				"QUERY_COUNTER_BITS for TRANSFORM_FEEDBACK_OVERFLOW queries is zero, skipping test");
   1031 		}
   1032 	}
   1033 
   1034 	/* Functional test deinit. Deletes created query objects */
   1035 	virtual void deinit()
   1036 	{
   1037 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1038 
   1039 		gl.deleteVertexArrays(1, &m_vao);
   1040 
   1041 		gl.deleteQueries(1, &m_overflow_query);
   1042 
   1043 		if (canTestStreamOverflow())
   1044 		{
   1045 			if (m_stream_overflow_query != NULL)
   1046 			{
   1047 				gl.deleteQueries(getMaxVertexStreams(), m_stream_overflow_query);
   1048 
   1049 				delete[] m_stream_overflow_query;
   1050 			}
   1051 		}
   1052 
   1053 		if (m_checker_program != NULL)
   1054 		{
   1055 			delete m_checker_program;
   1056 		}
   1057 
   1058 		gl.useProgram(0);
   1059 		gl.deleteProgram(m_program);
   1060 
   1061 		if (m_tf_buffer != NULL)
   1062 		{
   1063 			gl.deleteBuffers(m_tf_buffer_count, m_tf_buffer);
   1064 
   1065 			delete[] m_tf_buffer;
   1066 		}
   1067 
   1068 		TransformFeedbackOverflowQueryBaseTest::deinit();
   1069 	}
   1070 
   1071 	/*
   1072 	 Basic Checking Mechanism
   1073 
   1074 	 * Call BeginConditionalRender with mode QUERY_WAIT and with the given
   1075 	 query object as parameters. Draw something, then call EndConditional-
   1076 	 Render. If the expected result for the query is FALSE, expect
   1077 	 conditional render to discard the previous draw command.
   1078 
   1079 	 * If GL 4.5 or ARB_conditional_render_inverted is supported, call Begin-
   1080 	 ConditionalRender with mode QUERY_WAIT_INVERTED and with the given query
   1081 	 object as parameters. Draw something, then call EndConditionalRender. If
   1082 	 the expected result for the query is TRUE, expect conditional render to
   1083 	 discard the previous draw command.
   1084 
   1085 	 * Finally, check using GetQueryObjectiv with QUERY_RESULT that the result
   1086 	 of the query matches the expected result.
   1087 
   1088 	 * If GL 4.4 or ARB_query_buffer_object is supported then check the result
   1089 	 of the query against the expected result also by having a query buffer
   1090 	 bound at the time of calling GetQueryObjectiv.
   1091 	 */
   1092 	bool verifyQueryResult(GLuint query, GLboolean expected)
   1093 	{
   1094 		const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
   1095 		bool				  result = true;
   1096 		GLuint				  actual;
   1097 
   1098 		GLuint current_program = m_context.getContextInfo().getInt(GL_CURRENT_PROGRAM);
   1099 		GLuint checker_query, check_result;
   1100 
   1101 		// We'll use a PRIMITIVES_GENERATED query to test whether conditional
   1102 		// rendering actually executed the draw command or not. If the draw command
   1103 		// was discarded then the PRIMITIVES_GENERATED query should have a result
   1104 		// of zero.
   1105 		gl.genQueries(1, &checker_query);
   1106 
   1107 		gl.useProgram(m_checker_program->getProgram());
   1108 
   1109 		// Verify that conditional render discards the rendering if the expected
   1110 		// result is FALSE and renders otherwise.
   1111 		gl.beginConditionalRender(query, GL_QUERY_WAIT);
   1112 		gl.beginQuery(GL_PRIMITIVES_GENERATED, checker_query);
   1113 		gl.drawArrays(GL_POINTS, 0, 1);
   1114 		gl.endQuery(GL_PRIMITIVES_GENERATED);
   1115 		gl.endConditionalRender();
   1116 		gl.getQueryObjectuiv(checker_query, GL_QUERY_RESULT, &check_result);
   1117 		if (check_result != (GLuint)expected)
   1118 		{
   1119 			result = false;
   1120 		}
   1121 
   1122 		// Verify that an inverted conditional render discards the rendering if
   1123 		// the expected result is TRUE and renders otherwise.
   1124 		if (supportsConditionalRenderInverted())
   1125 		{
   1126 			gl.beginConditionalRender(query, GL_QUERY_WAIT_INVERTED);
   1127 			gl.beginQuery(GL_PRIMITIVES_GENERATED, checker_query);
   1128 			gl.drawArrays(GL_POINTS, 0, 1);
   1129 			gl.endQuery(GL_PRIMITIVES_GENERATED);
   1130 			gl.endConditionalRender();
   1131 			gl.getQueryObjectuiv(checker_query, GL_QUERY_RESULT, &check_result);
   1132 			if (check_result == (GLuint)expected)
   1133 			{
   1134 				result = false;
   1135 			}
   1136 		}
   1137 
   1138 		gl.useProgram(current_program);
   1139 
   1140 		// Verify that the result of the query matches the expected result.
   1141 		gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &actual);
   1142 		if ((GLboolean)actual != expected)
   1143 		{
   1144 			result = false;
   1145 		}
   1146 
   1147 		// Verify that the result of the query matches the expected result even
   1148 		// when using a query buffer.
   1149 		if (supportsQueryBufferObject())
   1150 		{
   1151 			const GLuint initValue = 0xDEADBEEF;
   1152 
   1153 			gl.genBuffers(1, &m_query_buffer);
   1154 			gl.bindBuffer(GL_QUERY_BUFFER, m_query_buffer);
   1155 			gl.bufferData(GL_QUERY_BUFFER, sizeof(initValue), &initValue, GL_STREAM_READ);
   1156 			gl.getQueryObjectuiv(query, GL_QUERY_RESULT, NULL);
   1157 			gl.getBufferSubData(GL_QUERY_BUFFER, 0, sizeof(actual), &actual);
   1158 			gl.deleteBuffers(1, &m_query_buffer);
   1159 
   1160 			if ((GLboolean)actual != expected)
   1161 			{
   1162 				result = false;
   1163 			}
   1164 		}
   1165 
   1166 		gl.deleteQueries(1, &checker_query);
   1167 
   1168 		return result;
   1169 	}
   1170 
   1171 	/* Verifies the result of all queries. There can only be up to 5 non-FALSE result queries as none of
   1172 	 the tests use more than 4 vertex streams so the rest is assumed to always have a FALSE result. */
   1173 	void verifyQueryResults(GLboolean any, GLboolean stream0, GLboolean stream1, GLboolean stream2 = GL_FALSE,
   1174 							GLboolean stream3 = GL_FALSE)
   1175 	{
   1176 		bool result = true;
   1177 
   1178 		// Verify the result of the TRANSFORM_FEEDBACK_OVERFLOW query.
   1179 		result &= verifyQueryResult(m_overflow_query, any);
   1180 
   1181 		if (supportsTransformFeedback3())
   1182 		{
   1183 			// Verify the result of the TRANSFORM_FEEDBACK_STREAM_OVERFLOW queries
   1184 			// corresponding to the first 4 vertex streams.
   1185 			result &= verifyQueryResult(m_stream_overflow_query[0], stream0);
   1186 			result &= verifyQueryResult(m_stream_overflow_query[1], stream1);
   1187 			result &= verifyQueryResult(m_stream_overflow_query[2], stream2);
   1188 			result &= verifyQueryResult(m_stream_overflow_query[3], stream3);
   1189 
   1190 			// Expect the rest of the TRANSFORM_FEEDBACK_STREAM_OVERFLOW queries
   1191 			// to have a FALSE result.
   1192 			for (GLuint i = 4; i < getMaxVertexStreams(); ++i)
   1193 			{
   1194 				result &= verifyQueryResult(m_stream_overflow_query[i], GL_FALSE);
   1195 			}
   1196 		}
   1197 
   1198 		if (!result)
   1199 		{
   1200 			TCU_FAIL("Failed to validate the results of the queries");
   1201 		}
   1202 	}
   1203 
   1204 	/* Single stream version of verifyQueryResults */
   1205 	void verifyQueryResults(GLboolean result)
   1206 	{
   1207 		verifyQueryResults(result, result, GL_FALSE, GL_FALSE, GL_FALSE);
   1208 	}
   1209 
   1210 	/* Compiles and links transform feedback program. */
   1211 	void buildTransformFeedbackProgram()
   1212 	{
   1213 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1214 
   1215 		GLint status;
   1216 
   1217 		m_program = gl.createProgram();
   1218 
   1219 		const char* vsSource = transformFeedbackVertexShader();
   1220 
   1221 		GLuint vShader = gl.createShader(GL_VERTEX_SHADER);
   1222 		gl.shaderSource(vShader, 1, (const char**)&vsSource, NULL);
   1223 		gl.compileShader(vShader);
   1224 		gl.getShaderiv(vShader, GL_COMPILE_STATUS, &status);
   1225 		if (status == GL_FALSE)
   1226 		{
   1227 			GLint infoLogLength = 0;
   1228 			gl.getShaderiv(vShader, GL_INFO_LOG_LENGTH, &infoLogLength);
   1229 
   1230 			std::vector<char> infoLogBuf(infoLogLength + 1);
   1231 			gl.getShaderInfoLog(vShader, (GLsizei)infoLogBuf.size(), NULL, &infoLogBuf[0]);
   1232 
   1233 			std::string infoLog = &infoLogBuf[0];
   1234 			m_testCtx.getLog().writeShader(QP_SHADER_TYPE_VERTEX, vsSource, false, infoLog.c_str());
   1235 
   1236 			gl.deleteShader(vShader);
   1237 
   1238 			TCU_FAIL("Failed to compile transform feedback vertex shader");
   1239 		}
   1240 		gl.attachShader(m_program, vShader);
   1241 		gl.deleteShader(vShader);
   1242 
   1243 		const char* gsSource = transformFeedbackGeometryShader();
   1244 
   1245 		if (gsSource)
   1246 		{
   1247 			GLuint gShader = gl.createShader(GL_GEOMETRY_SHADER);
   1248 			gl.shaderSource(gShader, 1, (const char**)&gsSource, NULL);
   1249 			gl.compileShader(gShader);
   1250 			gl.getShaderiv(gShader, GL_COMPILE_STATUS, &status);
   1251 			if (status == GL_FALSE)
   1252 			{
   1253 				GLint infoLogLength = 0;
   1254 				gl.getShaderiv(gShader, GL_INFO_LOG_LENGTH, &infoLogLength);
   1255 
   1256 				std::vector<char> infoLogBuf(infoLogLength + 1);
   1257 				gl.getShaderInfoLog(gShader, (GLsizei)infoLogBuf.size(), NULL, &infoLogBuf[0]);
   1258 
   1259 				std::string infoLog = &infoLogBuf[0];
   1260 				m_testCtx.getLog().writeShader(QP_SHADER_TYPE_GEOMETRY, gsSource, false, infoLog.c_str());
   1261 
   1262 				gl.deleteShader(gShader);
   1263 
   1264 				TCU_FAIL("Failed to compile transform feedback geometry shader");
   1265 			}
   1266 			gl.attachShader(m_program, gShader);
   1267 			gl.deleteShader(gShader);
   1268 		}
   1269 
   1270 		gl.transformFeedbackVaryings(m_program, varyingsCount(), varyings(), bufferMode());
   1271 		gl.linkProgram(m_program);
   1272 		gl.getProgramiv(m_program, GL_LINK_STATUS, &status);
   1273 		if (status == GL_FALSE)
   1274 		{
   1275 			GLint infoLogLength = 0;
   1276 			gl.getProgramiv(m_program, GL_INFO_LOG_LENGTH, &infoLogLength);
   1277 
   1278 			std::vector<char> infoLogBuf(infoLogLength + 1);
   1279 			gl.getProgramInfoLog(m_program, (GLsizei)infoLogBuf.size(), NULL, &infoLogBuf[0]);
   1280 
   1281 			std::string infoLog = &infoLogBuf[0];
   1282 			m_testCtx.getLog().writeShader(QP_SHADER_TYPE_VERTEX, vsSource, true, infoLog.c_str());
   1283 
   1284 			TCU_FAIL("Failed to link transform feedback program");
   1285 		}
   1286 
   1287 		gl.useProgram(m_program);
   1288 	}
   1289 
   1290 	/* Generates a number of transform feedback buffers and binds them. */
   1291 	void setupTransformFeedbackBuffers()
   1292 	{
   1293 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1294 
   1295 		m_tf_buffer_count = bufferCount();
   1296 
   1297 		m_tf_buffer = new GLuint[m_tf_buffer_count];
   1298 
   1299 		gl.genBuffers(m_tf_buffer_count, m_tf_buffer);
   1300 
   1301 		for (GLint i = 0; i < m_tf_buffer_count; ++i)
   1302 		{
   1303 			gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, m_tf_buffer[i]);
   1304 			gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, bufferSize(i), NULL, GL_DYNAMIC_COPY);
   1305 		}
   1306 	}
   1307 
   1308 	/* Starts all overflow queries. */
   1309 	void beginQueries()
   1310 	{
   1311 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1312 
   1313 		gl.beginQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW, m_overflow_query);
   1314 
   1315 		if (supportsTransformFeedback3())
   1316 		{
   1317 			for (GLuint i = 0; i < getMaxVertexStreams(); ++i)
   1318 			{
   1319 				gl.beginQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i, m_stream_overflow_query[i]);
   1320 			}
   1321 		}
   1322 	}
   1323 
   1324 	/* Stops all overflow queries. */
   1325 	void endQueries()
   1326 	{
   1327 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1328 
   1329 		gl.endQuery(GL_TRANSFORM_FEEDBACK_OVERFLOW);
   1330 
   1331 		if (supportsTransformFeedback3())
   1332 		{
   1333 			for (GLuint i = 0; i < getMaxVertexStreams(); ++i)
   1334 			{
   1335 				gl.endQueryIndexed(GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW, i);
   1336 			}
   1337 		}
   1338 	}
   1339 
   1340 	/* Draws a set of points to vertex stream #0 while having the overflow queries active. */
   1341 	void drawPoints(GLsizei count)
   1342 	{
   1343 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1344 
   1345 		beginQueries();
   1346 		gl.drawArrays(GL_POINTS, 0, count);
   1347 		endQueries();
   1348 	}
   1349 
   1350 	/* Draws a set of triangles to vertex stream #0 while having the overflow queries active. */
   1351 	void drawTriangles(GLsizei count)
   1352 	{
   1353 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1354 
   1355 		beginQueries();
   1356 		gl.drawArrays(GL_TRIANGLES, 0, count * 3);
   1357 		endQueries();
   1358 	}
   1359 
   1360 	/* Vertex shader to use for transform feedback. */
   1361 	virtual const char* transformFeedbackVertexShader() = 0;
   1362 
   1363 	/* Geometry shader to use for transform feedback. */
   1364 	virtual const char* transformFeedbackGeometryShader() = 0;
   1365 
   1366 	/* Returns the number of transform feedback varyings. */
   1367 	virtual GLsizei varyingsCount() = 0;
   1368 
   1369 	/* Returns the array of transform feedback varying names. */
   1370 	virtual const char** varyings() = 0;
   1371 
   1372 	/* Returns the transform feedback buffer mode. */
   1373 	virtual GLenum bufferMode() = 0;
   1374 
   1375 	/* Returns the number of transform feedback buffers. */
   1376 	virtual GLsizei bufferCount() = 0;
   1377 
   1378 	/* Returns the size of the specified transform feedback buffer. */
   1379 	virtual GLsizei bufferSize(GLint index) = 0;
   1380 
   1381 protected:
   1382 	GLuint				m_overflow_query;
   1383 	GLuint*				m_stream_overflow_query;
   1384 	GLuint				m_query_buffer;
   1385 	GLsizei				m_tf_buffer_count;
   1386 	GLuint*				m_tf_buffer;
   1387 	GLuint				m_vao;
   1388 	GLuint				m_program;
   1389 	glu::ShaderProgram* m_checker_program;
   1390 };
   1391 
   1392 /*
   1393  Base class for all single stream test cases.
   1394  */
   1395 class TransformFeedbackOverflowQuerySingleStreamBase : public TransformFeedbackOverflowQueryFunctionalBase
   1396 {
   1397 protected:
   1398 	TransformFeedbackOverflowQuerySingleStreamBase(deqp::Context& context, TransformFeedbackOverflowQueryTests::API api,
   1399 												   const char* name, const char* description)
   1400 		: TransformFeedbackOverflowQueryFunctionalBase(context, api, name, description)
   1401 	{
   1402 	}
   1403 
   1404 	/* Vertex shader to use for transform feedback. */
   1405 	virtual const char* transformFeedbackVertexShader()
   1406 	{
   1407 		return "#version 150 core\n"
   1408 			   "out float output1;\n"
   1409 			   "out float output2;\n"
   1410 			   "out float output3;\n"
   1411 			   "out float output4;\n"
   1412 			   "void main() {\n"
   1413 			   "    output1 = 1.0;\n"
   1414 			   "    output2 = 2.0;\n"
   1415 			   "    output3 = 3.0;\n"
   1416 			   "    output4 = 4.0;\n"
   1417 			   "}";
   1418 	}
   1419 
   1420 	/* No geometry shader for single stream test cases. */
   1421 	virtual const char* transformFeedbackGeometryShader()
   1422 	{
   1423 		return NULL;
   1424 	}
   1425 
   1426 	/* There are a total of 4 varyings. */
   1427 	virtual GLsizei varyingsCount()
   1428 	{
   1429 		return 4;
   1430 	}
   1431 
   1432 	/* The varying name list contains all outputs in order. */
   1433 	virtual const char** varyings()
   1434 	{
   1435 		static const char* vars[] = { "output1", "output2", "output3", "output4" };
   1436 		return vars;
   1437 	}
   1438 };
   1439 
   1440 /*
   1441  Test case #1 - Basic single stream, interleaved attributes.
   1442  */
   1443 class TransformFeedbackOverflowQueryBasicSingleStreamInterleavedAttribs
   1444 	: public TransformFeedbackOverflowQuerySingleStreamBase
   1445 {
   1446 public:
   1447 	TransformFeedbackOverflowQueryBasicSingleStreamInterleavedAttribs(deqp::Context&						   context,
   1448 																	  TransformFeedbackOverflowQueryTests::API api,
   1449 																	  const char*							   name)
   1450 		: TransformFeedbackOverflowQuerySingleStreamBase(context, api, name,
   1451 														 "Basic single stream, interleaved attributes.")
   1452 	{
   1453 	}
   1454 
   1455 	/* Use interleaved attributes. */
   1456 	virtual GLenum bufferMode()
   1457 	{
   1458 		return GL_INTERLEAVED_ATTRIBS;
   1459 	}
   1460 
   1461 	/* A single transform feedback buffer is enough. */
   1462 	virtual GLsizei bufferCount()
   1463 	{
   1464 		return 1;
   1465 	}
   1466 
   1467 	/* The transform feedback buffer should be able to capture exactly 10 vertices. */
   1468 	virtual GLsizei bufferSize(GLint index)
   1469 	{
   1470 		(void)index;
   1471 		return static_cast<GLsizei>(10 * sizeof(GLfloat) * varyingsCount());
   1472 	}
   1473 
   1474 	/* Test case iterate function. Contains the actual test case logic. */
   1475 	IterateResult iterate()
   1476 	{
   1477 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1478 
   1479 		// Call BeginTransformFeedback with mode POINTS.
   1480 		gl.beginTransformFeedback(GL_POINTS);
   1481 
   1482 		// Start the query, submit draw that results in feeding back exactly 10
   1483 		// points, then stop the query.
   1484 		drawPoints(10);
   1485 
   1486 		// Call EndTransformFeedback.
   1487 		gl.endTransformFeedback();
   1488 
   1489 		// Use the basic checking mechanism to validate that the result of the
   1490 		// query is FALSE.
   1491 		verifyQueryResults(GL_FALSE);
   1492 
   1493 		// Repeat the above steps, but this time feed back more than 10 vertices
   1494 		// and expect the result of the query to be TRUE.
   1495 		gl.beginTransformFeedback(GL_POINTS);
   1496 		drawPoints(11);
   1497 		gl.endTransformFeedback();
   1498 		verifyQueryResults(GL_TRUE);
   1499 
   1500 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1501 
   1502 		return STOP;
   1503 	}
   1504 };
   1505 
   1506 /*
   1507  Test case #2 - Basic single stream, separate attributes.
   1508  */
   1509 class TransformFeedbackOverflowQueryBasicSingleStreamSeparateAttribs
   1510 	: public TransformFeedbackOverflowQuerySingleStreamBase
   1511 {
   1512 public:
   1513 	TransformFeedbackOverflowQueryBasicSingleStreamSeparateAttribs(deqp::Context&							context,
   1514 																   TransformFeedbackOverflowQueryTests::API api,
   1515 																   const char*								name)
   1516 		: TransformFeedbackOverflowQuerySingleStreamBase(context, api, name,
   1517 														 "Basic single stream, separate attributes.")
   1518 	{
   1519 	}
   1520 
   1521 	/* Use separate attributes. */
   1522 	virtual GLenum bufferMode()
   1523 	{
   1524 		return GL_SEPARATE_ATTRIBS;
   1525 	}
   1526 
   1527 	/* We need a separate buffer for each varying. */
   1528 	virtual GLsizei bufferCount()
   1529 	{
   1530 		return varyingsCount();
   1531 	}
   1532 
   1533 	/* One of the transform feedback buffers should be able to capture exactly 12 vertices,
   1534 	 the others should be able to capture at least 15 vertices. */
   1535 	virtual GLsizei bufferSize(GLint index)
   1536 	{
   1537 		if (index == 1)
   1538 		{
   1539 			return 12 * sizeof(GLfloat);
   1540 		}
   1541 		else
   1542 		{
   1543 			return 15 * sizeof(GLfloat);
   1544 		}
   1545 	}
   1546 
   1547 	/* Test case iterate function. Contains the actual test case logic. */
   1548 	IterateResult iterate()
   1549 	{
   1550 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1551 
   1552 		// Call BeginTransformFeedback with mode TRIANGLES.
   1553 		gl.beginTransformFeedback(GL_TRIANGLES);
   1554 
   1555 		// Start the query, submit draw that results in feeding back exactly 4
   1556 		// triangles, then stop the query.
   1557 		drawTriangles(4);
   1558 
   1559 		// Call EndTransformFeedback.
   1560 		gl.endTransformFeedback();
   1561 
   1562 		// Use the basic checking mechanism to validate that the result of the
   1563 		// query is FALSE.
   1564 		verifyQueryResults(GL_FALSE);
   1565 
   1566 		// Repeat the above steps, but this time feed back exactly 5 triangles
   1567 		// and expect the result of the query to be TRUE.
   1568 		gl.beginTransformFeedback(GL_TRIANGLES);
   1569 		drawTriangles(5);
   1570 		gl.endTransformFeedback();
   1571 		verifyQueryResults(GL_TRUE);
   1572 
   1573 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1574 
   1575 		return STOP;
   1576 	}
   1577 };
   1578 
   1579 /*
   1580  Test case #3 - Advanced single stream, interleaved attributes.
   1581  */
   1582 class TransformFeedbackOverflowQueryAdvancedSingleStreamInterleavedAttribs
   1583 	: public TransformFeedbackOverflowQuerySingleStreamBase
   1584 {
   1585 public:
   1586 	TransformFeedbackOverflowQueryAdvancedSingleStreamInterleavedAttribs(deqp::Context& context,
   1587 																		 TransformFeedbackOverflowQueryTests::API api,
   1588 																		 const char*							  name)
   1589 		: TransformFeedbackOverflowQuerySingleStreamBase(context, api, name,
   1590 														 "Advanced single stream, interleaved attributes.")
   1591 	{
   1592 	}
   1593 
   1594 	/* Use interleaved attributes. */
   1595 	virtual GLenum bufferMode()
   1596 	{
   1597 		return GL_INTERLEAVED_ATTRIBS;
   1598 	}
   1599 
   1600 	/* A single transform feedback buffer is enough. */
   1601 	virtual GLsizei bufferCount()
   1602 	{
   1603 		return 1;
   1604 	}
   1605 
   1606 	/* The transform feedback buffer should be able to capture exactly 10 vertices. */
   1607 	virtual GLsizei bufferSize(GLint index)
   1608 	{
   1609 		(void)index;
   1610 		return static_cast<GLsizei>(10 * sizeof(GLfloat) * varyingsCount());
   1611 	}
   1612 
   1613 	/* Test case iterate function. Contains the actual test case logic. */
   1614 	IterateResult iterate()
   1615 	{
   1616 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1617 
   1618 		// If GL 4.0 and ARB_transform_feedback2 are not supported then skip this
   1619 		// test case.
   1620 		if (!supportsTransformFeedback2())
   1621 		{
   1622 			throw tcu::NotSupportedError("Required transform_feedback2 extension is not supported");
   1623 		}
   1624 
   1625 		// Call BeginTransformFeedback with mode POINTS.
   1626 		gl.beginTransformFeedback(GL_POINTS);
   1627 
   1628 		// Start the query, submit draw that results in feeding back exactly 8
   1629 		// triangles, then stop the query.
   1630 		drawPoints(8);
   1631 
   1632 		// Call PauseTransformFeedback.
   1633 		gl.pauseTransformFeedback();
   1634 
   1635 		// Use the basic checking mechanism to validate that the result of the
   1636 		// query is FALSE.
   1637 		verifyQueryResults(GL_FALSE);
   1638 
   1639 		// Start the query, submit draw that would result in feeding back more than
   1640 		// 10 points if transform feedback wasn't paused, then stop the query.
   1641 		drawPoints(11);
   1642 
   1643 		// Use the basic checking mechanism to validate that the result of the
   1644 		// query is FALSE.
   1645 		verifyQueryResults(GL_FALSE);
   1646 
   1647 		// Call ResumeTransformFeedback.
   1648 		gl.resumeTransformFeedback();
   1649 
   1650 		// Start the query, submit draw that results in feeding back exactly 1
   1651 		// point, then stop the query.
   1652 		drawPoints(1);
   1653 
   1654 		// Call PauseTransformFeedback.
   1655 		gl.pauseTransformFeedback();
   1656 
   1657 		// Use the basic checking mechanism to validate that the result of the
   1658 		// query is FALSE.
   1659 		verifyQueryResults(GL_FALSE);
   1660 
   1661 		// Call ResumeTransformFeedback.
   1662 		gl.resumeTransformFeedback();
   1663 
   1664 		// Start the query, submit draw that results in feeding back exactly 2
   1665 		// point, then stop the query.
   1666 		drawPoints(2);
   1667 
   1668 		// Call EndTransformFeedback.
   1669 		gl.endTransformFeedback();
   1670 
   1671 		// Use the basic checking mechanism to validate that the result of the
   1672 		// query is TRUE.
   1673 		verifyQueryResults(GL_TRUE);
   1674 
   1675 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1676 
   1677 		return STOP;
   1678 	}
   1679 };
   1680 
   1681 /*
   1682  Test case #4 - Advanced single stream, separate attributes.
   1683  */
   1684 class TransformFeedbackOverflowQueryAdvancedSingleStreamSeparateAttribs
   1685 	: public TransformFeedbackOverflowQuerySingleStreamBase
   1686 {
   1687 public:
   1688 	TransformFeedbackOverflowQueryAdvancedSingleStreamSeparateAttribs(deqp::Context&						   context,
   1689 																	  TransformFeedbackOverflowQueryTests::API api,
   1690 																	  const char*							   name)
   1691 		: TransformFeedbackOverflowQuerySingleStreamBase(context, api, name,
   1692 														 "Advanced single stream, separate attributes.")
   1693 	{
   1694 	}
   1695 
   1696 	/* Use separate attributes. */
   1697 	virtual GLenum bufferMode()
   1698 	{
   1699 		return GL_SEPARATE_ATTRIBS;
   1700 	}
   1701 
   1702 	/* We need a separate buffer for each varying. */
   1703 	virtual GLsizei bufferCount()
   1704 	{
   1705 		return varyingsCount();
   1706 	}
   1707 
   1708 	/* One of the transform feedback buffers should be able to capture exactly 12 vertices,
   1709 	 the others should be able to capture at least 15 vertices. */
   1710 	virtual GLsizei bufferSize(GLint index)
   1711 	{
   1712 		if (index == 2)
   1713 		{
   1714 			return 12 * sizeof(GLfloat);
   1715 		}
   1716 		else
   1717 		{
   1718 			return 15 * sizeof(GLfloat);
   1719 		}
   1720 	}
   1721 
   1722 	/* Test case iterate function. Contains the actual test case logic. */
   1723 	IterateResult iterate()
   1724 	{
   1725 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1726 
   1727 		// If GL 4.0 and ARB_transform_feedback2 are not supported then skip this
   1728 		// test case.
   1729 		if (!supportsTransformFeedback2())
   1730 		{
   1731 			throw tcu::NotSupportedError("Required transform_feedback2 extension is not supported");
   1732 		}
   1733 
   1734 		// Call BeginTransformFeedback with mode TRIANGLES.
   1735 		gl.beginTransformFeedback(GL_TRIANGLES);
   1736 
   1737 		// Start the query, submit draw that results in feeding back exactly 2
   1738 		// triangles, then stop the query.
   1739 		drawTriangles(2);
   1740 
   1741 		// Call PauseTransformFeedback.
   1742 		gl.pauseTransformFeedback();
   1743 
   1744 		// Use the basic checking mechanism to validate that the result of the
   1745 		// query is FALSE.
   1746 		verifyQueryResults(GL_FALSE);
   1747 
   1748 		// Start the query, submit draw that would result in feeding back more than
   1749 		// 4 triangles if transform feedback wasn't paused, then stop the query.
   1750 		drawTriangles(4);
   1751 
   1752 		// Use the basic checking mechanism to validate that the result of the
   1753 		// query is FALSE.
   1754 		verifyQueryResults(GL_FALSE);
   1755 
   1756 		// Call ResumeTransformFeedback.
   1757 		gl.resumeTransformFeedback();
   1758 
   1759 		// Start the query, submit draw that results in feeding back exactly 2
   1760 		// triangles, then stop the query.
   1761 		drawTriangles(2);
   1762 
   1763 		// Call PauseTransformFeedback.
   1764 		gl.pauseTransformFeedback();
   1765 
   1766 		// Use the basic checking mechanism to validate that the result of the
   1767 		// query is FALSE.
   1768 		verifyQueryResults(GL_FALSE);
   1769 
   1770 		// Call ResumeTransformFeedback.
   1771 		gl.resumeTransformFeedback();
   1772 
   1773 		// Start the query, submit draw that results in feeding back exactly 1
   1774 		// triangles, then stop the query.
   1775 		drawTriangles(1);
   1776 
   1777 		// Call EndTransformFeedback.
   1778 		gl.endTransformFeedback();
   1779 
   1780 		// Use the basic checking mechanism to validate that the result of the
   1781 		// query is TRUE.
   1782 		verifyQueryResults(GL_TRUE);
   1783 
   1784 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1785 
   1786 		return STOP;
   1787 	}
   1788 };
   1789 
   1790 /*
   1791  Base class for all multiple stream test cases.
   1792  */
   1793 class TransformFeedbackOverflowQueryMultipleStreamsBase : public TransformFeedbackOverflowQueryFunctionalBase
   1794 {
   1795 protected:
   1796 	TransformFeedbackOverflowQueryMultipleStreamsBase(deqp::Context&						   context,
   1797 													  TransformFeedbackOverflowQueryTests::API api, const char* name,
   1798 													  const char* description)
   1799 		: TransformFeedbackOverflowQueryFunctionalBase(context, api, name, description)
   1800 	{
   1801 	}
   1802 
   1803 	/* Vertex shader to use for transform feedback. */
   1804 	virtual const char* transformFeedbackVertexShader()
   1805 	{
   1806 		return "#version 150 core\n"
   1807 			   "void main() {\n"
   1808 			   "}";
   1809 	}
   1810 
   1811 	/* Use interleaved attributes. */
   1812 	virtual GLenum bufferMode()
   1813 	{
   1814 		return GL_INTERLEAVED_ATTRIBS;
   1815 	}
   1816 
   1817 	/* Always use 4 transform feedback buffers. */
   1818 	virtual GLsizei bufferCount()
   1819 	{
   1820 		return 4;
   1821 	}
   1822 
   1823 	/* Draws a set of points to each vertex stream while having the overflow queries active. */
   1824 	void drawStreams(GLsizei count0, GLsizei count1 = 0, GLsizei count2 = 0, GLsizei count3 = 0)
   1825 	{
   1826 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1827 
   1828 		GLint streamLoc = gl.getUniformLocation(m_program, "stream");
   1829 
   1830 		beginQueries();
   1831 
   1832 		gl.uniform1ui(streamLoc, 0);
   1833 		gl.drawArrays(GL_POINTS, 0, count0);
   1834 
   1835 		gl.uniform1ui(streamLoc, 1);
   1836 		gl.drawArrays(GL_POINTS, 0, count1);
   1837 
   1838 		gl.uniform1ui(streamLoc, 2);
   1839 		gl.drawArrays(GL_POINTS, 0, count2);
   1840 
   1841 		gl.uniform1ui(streamLoc, 3);
   1842 		gl.drawArrays(GL_POINTS, 0, count3);
   1843 
   1844 		endQueries();
   1845 	}
   1846 };
   1847 
   1848 /*
   1849  Test case #5 - Advanced multiple streams, one buffer per stream.
   1850  */
   1851 class TransformFeedbackOverflowQueryMultipleStreamsOneBufferPerStream
   1852 	: public TransformFeedbackOverflowQueryMultipleStreamsBase
   1853 {
   1854 public:
   1855 	TransformFeedbackOverflowQueryMultipleStreamsOneBufferPerStream(deqp::Context&							 context,
   1856 																	TransformFeedbackOverflowQueryTests::API api,
   1857 																	const char*								 name)
   1858 		: TransformFeedbackOverflowQueryMultipleStreamsBase(context, api, name,
   1859 															"Advanced multiple streams, one buffer per stream.")
   1860 	{
   1861 	}
   1862 
   1863 	/* Geometry shader to use for transform feedback. */
   1864 	virtual const char* transformFeedbackGeometryShader()
   1865 	{
   1866 		return "#version 150 core\n"
   1867 			   "#extension GL_ARB_gpu_shader5 : require\n"
   1868 			   "layout(points) in;\n"
   1869 			   "layout(points, max_vertices = 1) out;\n"
   1870 			   "layout(stream=0) out float output1;\n"
   1871 			   "layout(stream=1) out float output2;\n"
   1872 			   "layout(stream=2) out float output3;\n"
   1873 			   "layout(stream=3) out float output4;\n"
   1874 			   "uniform uint stream;\n"
   1875 			   "void main() {\n"
   1876 			   "    if (stream == 0) {\n"
   1877 			   "        output1 = 1.0;\n"
   1878 			   "        EmitStreamVertex(0);\n"
   1879 			   "        EndStreamPrimitive(0);\n"
   1880 			   "    }\n"
   1881 			   "    if (stream == 1) {\n"
   1882 			   "        output2 = 2.0;\n"
   1883 			   "        EmitStreamVertex(1);\n"
   1884 			   "        EndStreamPrimitive(1);\n"
   1885 			   "    }\n"
   1886 			   "    if (stream == 2) {\n"
   1887 			   "        output3 = 3.0;\n"
   1888 			   "        EmitStreamVertex(2);\n"
   1889 			   "        EndStreamPrimitive(2);\n"
   1890 			   "    }\n"
   1891 			   "    if (stream == 3) {\n"
   1892 			   "        output4 = 4.0;\n"
   1893 			   "        EmitStreamVertex(3);\n"
   1894 			   "        EndStreamPrimitive(3);\n"
   1895 			   "    }\n"
   1896 			   "}";
   1897 	}
   1898 
   1899 	/* Together with the separators there are a total of 7 varyings. */
   1900 	virtual GLsizei varyingsCount()
   1901 	{
   1902 		return 7;
   1903 	}
   1904 
   1905 	/* Each output goes to different buffer. The mapping between vertex stream outputs and transform feedback buffers is non-identity. */
   1906 	virtual const char** varyings()
   1907 	{
   1908 		static const char* vars[] = { "output4", "gl_NextBuffer", "output3", "gl_NextBuffer",
   1909 									  "output2", "gl_NextBuffer", "output1" };
   1910 		return vars;
   1911 	}
   1912 
   1913 	/* The size of the transform feedback buffers should be enough to be able to capture exactly 10 vertices for each vertex stream. */
   1914 	virtual GLsizei bufferSize(GLint index)
   1915 	{
   1916 		(void)index;
   1917 		return 10 * sizeof(GLfloat);
   1918 	}
   1919 
   1920 	/* Test case iterate function. Contains the actual test case logic. */
   1921 	IterateResult iterate()
   1922 	{
   1923 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1924 
   1925 		// If GL 4.0 and ARB_transform_feedback3 are not supported then skip this
   1926 		// test case.
   1927 		if (!supportsTransformFeedback3())
   1928 		{
   1929 			throw tcu::NotSupportedError("Required transform_feedback3 extension is not supported");
   1930 		}
   1931 
   1932 		// If GL 4.0 and ARB_gpu_shader5 are not supported then skip this
   1933 		// test case.
   1934 		if (!supportsGpuShader5())
   1935 		{
   1936 			throw tcu::NotSupportedError("Required gpu_shader5 extension is not supported");
   1937 		}
   1938 
   1939 		// Call BeginTransformFeedback with mode POINTS.
   1940 		gl.beginTransformFeedback(GL_POINTS);
   1941 
   1942 		// Start all queries, submit draw that results in feeding back exactly 8
   1943 		// points for all four vertex streams, then stop the queries.
   1944 		drawStreams(8, 8, 8, 8);
   1945 
   1946 		// Call PauseTransformFeedback.
   1947 		gl.pauseTransformFeedback();
   1948 
   1949 		// Use the basic checking mechanism to validate that the result of the
   1950 		// queries are all FALSE.
   1951 		verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
   1952 
   1953 		// Start the queries, submit draw that would result in feeding back more
   1954 		// than 10 points for all four vertex streams if transform feedback wasn't
   1955 		// paused, then stop the queries.
   1956 		drawStreams(11, 11, 11, 11);
   1957 
   1958 		// Use the basic checking mechanism to validate that the result of the
   1959 		// queries are all FALSE.
   1960 		verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
   1961 
   1962 		// Call ResumeTransformFeedback.
   1963 		gl.resumeTransformFeedback();
   1964 
   1965 		// Start the queries, submit draw that results in feeding back exactly 3
   1966 		// points only for vertex streams #1 and #3, then stop the queries.
   1967 		drawStreams(0, 3, 0, 3);
   1968 
   1969 		// Call PauseTransformFeedback.
   1970 		gl.pauseTransformFeedback();
   1971 
   1972 		// Use the basic checking mechanism to validate that the result of the
   1973 		// queries are all FALSE, except for the TRANSFORM_FEEDBACK_OVERFLOW
   1974 		// query, and the TRANSFORM_FEEDBACK_STREAM_OVERFLOW queries for
   1975 		// vertex streams #1 and #3, which should have a TRUE result.
   1976 		verifyQueryResults(GL_TRUE, GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
   1977 
   1978 		// Call ResumeTransformFeedback.
   1979 		gl.resumeTransformFeedback();
   1980 
   1981 		// Start the queries, submit draw that results in feeding back exactly 2
   1982 		// points only for vertex streams #0 and #2, then stop the queries.
   1983 		drawStreams(2, 0, 2, 0);
   1984 
   1985 		// Call PauseTransformFeedback.
   1986 		gl.pauseTransformFeedback();
   1987 
   1988 		// Use the basic checking mechanism to validate that the result of the
   1989 		// queries are all FALSE.
   1990 		verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
   1991 
   1992 		// Call ResumeTransformFeedback.
   1993 		gl.resumeTransformFeedback();
   1994 
   1995 		// Start the queries, submit draw that results in feeding back exactly 1
   1996 		// point for vertex streams #2 and #3, then stop the queries.
   1997 		drawStreams(0, 0, 1, 1);
   1998 
   1999 		// Call EndTransformFeedback.
   2000 		gl.endTransformFeedback();
   2001 
   2002 		// Use the basic checking mechanism to validate that the result of the
   2003 		// queries are all FALSE, except for the TRANSFORM_FEEDBACK_OVERFLOW
   2004 		// query, and the TRANSFORM_FEEDBACK_STREAM_OVERFLOW queries for
   2005 		// vertex streams #2 and #3, which should have a TRUE result.
   2006 		verifyQueryResults(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE);
   2007 
   2008 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   2009 
   2010 		return STOP;
   2011 	}
   2012 };
   2013 
   2014 /*
   2015  Test case #6 - Advanced multiple streams, multiple buffers per stream.
   2016  */
   2017 class TransformFeedbackOverflowQueryMultipleStreamsMultipleBufferPerStream
   2018 	: public TransformFeedbackOverflowQueryMultipleStreamsBase
   2019 {
   2020 public:
   2021 	TransformFeedbackOverflowQueryMultipleStreamsMultipleBufferPerStream(deqp::Context& context,
   2022 																		 TransformFeedbackOverflowQueryTests::API api,
   2023 																		 const char*							  name)
   2024 		: TransformFeedbackOverflowQueryMultipleStreamsBase(context, api, name,
   2025 															"Advanced multiple streams, multiple buffers per stream.")
   2026 	{
   2027 	}
   2028 
   2029 	/* Geometry shader to use for transform feedback. */
   2030 	virtual const char* transformFeedbackGeometryShader()
   2031 	{
   2032 		return "#version 150 core\n"
   2033 			   "#extension GL_ARB_gpu_shader5 : require\n"
   2034 			   "layout(points) in;\n"
   2035 			   "layout(points, max_vertices = 1) out;\n"
   2036 			   "layout(stream=0) out float output1;\n"
   2037 			   "layout(stream=0) out float output2;\n"
   2038 			   "layout(stream=1) out float output3;\n"
   2039 			   "layout(stream=1) out float output4;\n"
   2040 			   "uniform uint stream;\n"
   2041 			   "void main() {\n"
   2042 			   "    if (stream == 0) {\n"
   2043 			   "        output1 = 1.0;\n"
   2044 			   "        output2 = 2.0;\n"
   2045 			   "        EmitStreamVertex(0);\n"
   2046 			   "        EndStreamPrimitive(0);\n"
   2047 			   "    }\n"
   2048 			   "    if (stream == 1) {\n"
   2049 			   "        output3 = 3.0;\n"
   2050 			   "        output4 = 4.0;\n"
   2051 			   "        EmitStreamVertex(1);\n"
   2052 			   "        EndStreamPrimitive(1);\n"
   2053 			   "    }\n"
   2054 			   "}";
   2055 	}
   2056 
   2057 	/* Together with the separators there are a total of 7 varyings. */
   2058 	virtual GLsizei varyingsCount()
   2059 	{
   2060 		return 7;
   2061 	}
   2062 
   2063 	/* Vertex stream #0 is captured by transform feedback buffers #1 and #2, while
   2064 	 vertex stream #1 is captured by transform feedback buffers #3 and #0. */
   2065 	virtual const char** varyings()
   2066 	{
   2067 		static const char* vars[] = { "output4", "gl_NextBuffer", "output1", "gl_NextBuffer",
   2068 									  "output2", "gl_NextBuffer", "output3" };
   2069 		return vars;
   2070 	}
   2071 
   2072 	/* Transform feedback buffers #0 and #1 should be able to capture exactly 10 vertices, while
   2073 	 transform feedback buffers #2 and #3 should be able to capture exactly 20 vertices. */
   2074 	virtual GLsizei bufferSize(GLint index)
   2075 	{
   2076 		if (index < 2)
   2077 		{
   2078 			return 10 * sizeof(GLfloat);
   2079 		}
   2080 		else
   2081 		{
   2082 			return 20 * sizeof(GLfloat);
   2083 		}
   2084 	}
   2085 
   2086 	/* Test case iterate function. Contains the actual test case logic. */
   2087 	IterateResult iterate()
   2088 	{
   2089 		const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2090 
   2091 		// If GL 4.0 and ARB_transform_feedback3 are not supported then skip this
   2092 		// test case.
   2093 		if (!supportsTransformFeedback3())
   2094 		{
   2095 			throw tcu::NotSupportedError("Required transform_feedback3 extension is not supported");
   2096 		}
   2097 
   2098 		// If GL 4.0 and ARB_gpu_shader5 are not supported then skip this
   2099 		// test case.
   2100 		if (!supportsGpuShader5())
   2101 		{
   2102 			throw tcu::NotSupportedError("Required gpu_shader5 extension is not supported");
   2103 		}
   2104 
   2105 		// Call BeginTransformFeedback with mode POINTS.
   2106 		gl.beginTransformFeedback(GL_POINTS);
   2107 
   2108 		// Start all queries, submit draw that results in feeding back exactly 8
   2109 		// points to both vertex streams, then stop the queries.
   2110 		drawStreams(8, 8);
   2111 
   2112 		// Call PauseTransformFeedback.
   2113 		gl.pauseTransformFeedback();
   2114 
   2115 		// Use the basic checking mechanism to validate that the result of the
   2116 		// queries are all FALSE.
   2117 		verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE);
   2118 
   2119 		// Start the queries, submit draw that would result in feeding back more
   2120 		// than 10 points for both vertex streams if transform feedback wasn't
   2121 		// paused, then stop the queries.
   2122 		drawStreams(11, 11);
   2123 
   2124 		// Use the basic checking mechanism to validate that the result of the
   2125 		// queries are all FALSE.
   2126 		verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE);
   2127 
   2128 		// Call ResumeTransformFeedback.
   2129 		gl.resumeTransformFeedback();
   2130 
   2131 		// Start the queries, submit draw that results in feeding back exactly 1
   2132 		// point for vertex stream #0 and exactly 3 points for vertex stream #1,
   2133 		// then stop the queries.
   2134 		drawStreams(1, 3);
   2135 
   2136 		// Call PauseTransformFeedback.
   2137 		gl.pauseTransformFeedback();
   2138 
   2139 		// Use the basic checking mechanism to validate that the result of the
   2140 		// queries are all FALSE, except for the TRANSFORM_FEEDBACK_OVERFLOW
   2141 		// query, and the TRANSFORM_FEEDBACK_STREAM_OVERFLOW query for vertex
   2142 		// stream #1, which should have a TRUE result.
   2143 		verifyQueryResults(GL_TRUE, GL_FALSE, GL_TRUE);
   2144 
   2145 		// Call ResumeTransformFeedback.
   2146 		gl.resumeTransformFeedback();
   2147 
   2148 		// Start the queries, submit draw that results in feeding back exactly 1
   2149 		// point only for vertex stream #0, then stop the queries.
   2150 		drawStreams(1, 0);
   2151 
   2152 		// Call PauseTransformFeedback.
   2153 		gl.pauseTransformFeedback();
   2154 
   2155 		// Use the basic checking mechanism to validate that the result of the
   2156 		// queries are all FALSE.
   2157 		verifyQueryResults(GL_FALSE, GL_FALSE, GL_FALSE);
   2158 
   2159 		// Call ResumeTransformFeedback.
   2160 		gl.resumeTransformFeedback();
   2161 
   2162 		// Start the queries, submit draw that results in feeding back exactly 1
   2163 		// point for vertex streams #0 and #1, then stop the queries.
   2164 		drawStreams(1, 1);
   2165 
   2166 		// Call EndTransformFeedback.
   2167 		gl.endTransformFeedback();
   2168 
   2169 		// Use the basic checking mechanism to validate that the result of the
   2170 		// queries are all FALSE, except for the TRANSFORM_FEEDBACK_OVERFLOW
   2171 		// query, and the TRANSFORM_FEEDBACK_STREAM_OVERFLOW queries for
   2172 		// vertex streams #0 and #1, which should have a TRUE result.
   2173 		verifyQueryResults(GL_TRUE, GL_TRUE, GL_TRUE);
   2174 
   2175 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   2176 
   2177 		return STOP;
   2178 	}
   2179 };
   2180 
   2181 const char* apiToTestName(TransformFeedbackOverflowQueryTests::API api)
   2182 {
   2183 	switch (api)
   2184 	{
   2185 	case TransformFeedbackOverflowQueryTests::API_GL_ARB_transform_feedback_overflow_query:
   2186 		return "transform_feedback_overflow_query_ARB";
   2187 	}
   2188 	DE_ASSERT(0);
   2189 	return "";
   2190 }
   2191 
   2192 /** Constructor.
   2193  *
   2194  *  @param context Rendering context.
   2195  *  @param api     API to test (core vs ARB extension)
   2196  **/
   2197 TransformFeedbackOverflowQueryTests::TransformFeedbackOverflowQueryTests(deqp::Context& context, API api)
   2198 	: TestCaseGroup(context, apiToTestName(api), "Verifies \"transform_feedback_overflow_query\" functionality")
   2199 	, m_api(api)
   2200 {
   2201 	/* Left blank on purpose */
   2202 }
   2203 
   2204 /** Destructor.
   2205  *
   2206  **/
   2207 TransformFeedbackOverflowQueryTests::~TransformFeedbackOverflowQueryTests()
   2208 {
   2209 }
   2210 
   2211 /** Initializes the texture_barrier test group.
   2212  *
   2213  **/
   2214 void TransformFeedbackOverflowQueryTests::init(void)
   2215 {
   2216 	addChild(new TransformFeedbackOverflowQueryImplDepState(m_context, m_api, "implementation-dependent-state"));
   2217 	addChild(new TransformFeedbackOverflowQueryDefaultState(m_context, m_api, "default-context-state"));
   2218 	addChild(new TransformFeedbackOverflowQueryStateUpdate(m_context, m_api, "context-state-update"));
   2219 	addChild(new TransformFeedbackOverflowQueryErrorInvalidIndex(m_context, m_api, "error-invalid-index"));
   2220 	addChild(new TransformFeedbackOverflowQueryErrorAlreadyActive(m_context, m_api, "error-already-active"));
   2221 	addChild(new TransformFeedbackOverflowQueryErrorIncompatibleTarget(m_context, m_api, "error-incompatible-target"));
   2222 	addChild(new TransformFeedbackOverflowQueryErrorNoActiveQuery(m_context, m_api, "error-no-active-query"));
   2223 	addChild(new TransformFeedbackOverflowQueryBasicSingleStreamInterleavedAttribs(
   2224 		m_context, m_api, "basic-single-stream-interleaved-attribs"));
   2225 	addChild(new TransformFeedbackOverflowQueryBasicSingleStreamSeparateAttribs(
   2226 		m_context, m_api, "basic-single-stream-separate-attribs"));
   2227 	addChild(new TransformFeedbackOverflowQueryAdvancedSingleStreamInterleavedAttribs(
   2228 		m_context, m_api, "advanced-single-stream-interleaved-attribs"));
   2229 	addChild(new TransformFeedbackOverflowQueryAdvancedSingleStreamSeparateAttribs(
   2230 		m_context, m_api, "advanced-single-stream-separate-attribs"));
   2231 	addChild(new TransformFeedbackOverflowQueryMultipleStreamsOneBufferPerStream(
   2232 		m_context, m_api, "multiple-streams-one-buffer-per-stream"));
   2233 	addChild(new TransformFeedbackOverflowQueryMultipleStreamsMultipleBufferPerStream(
   2234 		m_context, m_api, "multiple-streams-multiple-buffers-per-stream"));
   2235 }
   2236 } /* glcts namespace */
   2237