Home | History | Annotate | Download | only in gl
      1 /*-------------------------------------------------------------------------
      2  * OpenGL Conformance Test Suite
      3  * -----------------------------
      4  *
      5  * Copyright (c) 2015-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  */ /*!
     26  * \file  gl4cDirectStateAccessXFBTests.cpp
     27  * \brief Conformance tests for the Direct State Access feature functionality (Transform Feedbeck access part).
     28  */ /*-----------------------------------------------------------------------------------------------------------*/
     29 
     30 /* Includes. */
     31 #include "gl4cDirectStateAccessTests.hpp"
     32 
     33 #include "deSharedPtr.hpp"
     34 
     35 #include "gluContextInfo.hpp"
     36 #include "gluDefs.hpp"
     37 #include "gluPixelTransfer.hpp"
     38 #include "gluStrUtil.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 gl4cts
     50 {
     51 namespace DirectStateAccess
     52 {
     53 namespace TransformFeedback
     54 {
     55 /******************************** Creation Test Implementation   ********************************/
     56 
     57 /** @brief Creation Test constructor.
     58  *
     59  *  @param [in] context     OpenGL context.
     60  */
     61 CreationTest::CreationTest(deqp::Context& context)
     62 	: deqp::TestCase(context, "xfb_creation", "Transform Feedback Creation Test")
     63 {
     64 	/* Intentionally left blank. */
     65 }
     66 
     67 /** @brief Iterate Creation Test cases.
     68  *
     69  *  @return Iteration result.
     70  */
     71 tcu::TestNode::IterateResult CreationTest::iterate()
     72 {
     73 	/* Shortcut for GL functionality */
     74 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
     75 
     76 	/* Get context setup. */
     77 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
     78 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
     79 
     80 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
     81 	{
     82 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
     83 
     84 		return STOP;
     85 	}
     86 
     87 	/* Running tests. */
     88 	bool is_ok	= true;
     89 	bool is_error = false;
     90 
     91 	/* Transform feedback objects */
     92 	static const glw::GLuint xfb_count = 2;
     93 
     94 	glw::GLuint xfb_dsa[xfb_count]	= {};
     95 	glw::GLuint xfb_legacy[xfb_count] = {};
     96 
     97 	try
     98 	{
     99 		/* Sanity default setup. */
    100 		gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
    101 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback have failed");
    102 
    103 		/* Check legacy way. */
    104 		gl.genTransformFeedbacks(xfb_count, xfb_legacy);
    105 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTransformFeedbacks have failed");
    106 
    107 		for (glw::GLuint i = 0; i < xfb_count; ++i)
    108 		{
    109 			if (gl.isTransformFeedback(xfb_legacy[i]))
    110 			{
    111 				is_ok = false;
    112 
    113 				/* Log. */
    114 				m_context.getTestContext().getLog()
    115 					<< tcu::TestLog::Message
    116 					<< "GenTransformFeedbacks has created defualt objects, but only shall reserve names for them."
    117 					<< tcu::TestLog::EndMessage;
    118 			}
    119 		}
    120 
    121 		/* Check direct state access way. */
    122 		gl.createTransformFeedbacks(xfb_count, xfb_dsa);
    123 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
    124 
    125 		for (glw::GLuint i = 0; i < xfb_count; ++i)
    126 		{
    127 			if (!gl.isTransformFeedback(xfb_dsa[i]))
    128 			{
    129 				is_ok = false;
    130 
    131 				/* Log. */
    132 				m_context.getTestContext().getLog() << tcu::TestLog::Message
    133 													<< "CreateTransformFeedbacks has not created defualt objects."
    134 													<< tcu::TestLog::EndMessage;
    135 			}
    136 		}
    137 
    138 		/* Check binding point. */
    139 		glw::GLint xfb_binding_point = -1;
    140 
    141 		gl.getIntegerv(GL_TRANSFORM_FEEDBACK_BINDING, &xfb_binding_point);
    142 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv have failed");
    143 
    144 		if (0 != xfb_binding_point)
    145 		{
    146 			if (-1 == xfb_binding_point)
    147 			{
    148 				m_context.getTestContext().getLog() << tcu::TestLog::Message
    149 													<< "glGetIntegerv used with GL_TRANSFORM_FEEDBACK_BINDING have not "
    150 													   "returned anything and did not generate error."
    151 													<< tcu::TestLog::EndMessage;
    152 
    153 				throw 0;
    154 			}
    155 			else
    156 			{
    157 				m_context.getTestContext().getLog() << tcu::TestLog::Message
    158 													<< "The usage of glCreateTransformFeedbacks have changed "
    159 													   "GL_TRANSFORM_FEEDBACK_BINDING binding point."
    160 													<< tcu::TestLog::EndMessage;
    161 
    162 				is_ok = false;
    163 			}
    164 		}
    165 	}
    166 	catch (...)
    167 	{
    168 		is_ok	= false;
    169 		is_error = true;
    170 	}
    171 
    172 	/* Cleanup. */
    173 	for (glw::GLuint i = 0; i < xfb_count; ++i)
    174 	{
    175 		if (xfb_legacy[i])
    176 		{
    177 			gl.deleteTransformFeedbacks(1, &xfb_legacy[i]);
    178 
    179 			xfb_legacy[i] = 0;
    180 		}
    181 
    182 		if (xfb_dsa[i])
    183 		{
    184 			gl.deleteTransformFeedbacks(1, &xfb_dsa[i]);
    185 
    186 			xfb_dsa[i] = 0;
    187 		}
    188 	}
    189 
    190 	/* Result's setup. */
    191 	if (is_ok)
    192 	{
    193 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    194 	}
    195 	else
    196 	{
    197 		if (is_error)
    198 		{
    199 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
    200 		}
    201 		else
    202 		{
    203 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    204 		}
    205 	}
    206 
    207 	return STOP;
    208 }
    209 
    210 /******************************** Defaults Test Implementation   ********************************/
    211 
    212 /** @brief Defaults Test constructor.
    213  *
    214  *  @param [in] context     OpenGL context.
    215  */
    216 DefaultsTest::DefaultsTest(deqp::Context& context)
    217 	: deqp::TestCase(context, "xfb_defaults", "Transform Feedback Defaults Test")
    218 	, m_gl_getTransformFeedbackiv(DE_NULL)
    219 	, m_gl_getTransformFeedbacki_v(DE_NULL)
    220 	, m_gl_getTransformFeedbacki64_v(DE_NULL)
    221 	, m_xfb_dsa(0)
    222 	, m_xfb_indexed_binding_points_count(0)
    223 {
    224 	/* Intentionally left blank. */
    225 }
    226 
    227 /** @brief Iterate Defaults Test cases.
    228  *
    229  *  @return Iteration result.
    230  */
    231 tcu::TestNode::IterateResult DefaultsTest::iterate()
    232 {
    233 	/* Get context setup. */
    234 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    235 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
    236 
    237 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    238 	{
    239 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
    240 
    241 		return STOP;
    242 	}
    243 
    244 	/* Running tests. */
    245 	bool is_ok	= true;
    246 	bool is_error = false;
    247 
    248 	try
    249 	{
    250 		prepare();
    251 
    252 		is_ok &= testBuffersBindingPoints();
    253 		is_ok &= testBuffersDimensions();
    254 		is_ok &= testActive();
    255 		is_ok &= testPaused();
    256 	}
    257 	catch (...)
    258 	{
    259 		is_ok	= false;
    260 		is_error = true;
    261 	}
    262 
    263 	/* Clean up. */
    264 	clean();
    265 
    266 	/* Result's setup. */
    267 	if (is_ok)
    268 	{
    269 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    270 	}
    271 	else
    272 	{
    273 		if (is_error)
    274 		{
    275 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
    276 		}
    277 		else
    278 		{
    279 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    280 		}
    281 	}
    282 
    283 	return STOP;
    284 }
    285 
    286 /** @brief Create XFB and Buffer Objects. Prepare function pointers.
    287  *
    288  *  @note The function may throw if unexpected error has occured.
    289  *
    290  *  @return True if test succeeded, false otherwise.
    291  */
    292 void DefaultsTest::prepare()
    293 {
    294 	/* Shortcut for GL functionality */
    295 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    296 
    297 	/* Fetching function pointers. */
    298 	m_gl_getTransformFeedbackiv	= (GetTransformFeedbackiv_ProcAddress)gl.getTransformFeedbackiv;
    299 	m_gl_getTransformFeedbacki_v   = (GetTransformFeedbacki_v_ProcAddress)gl.getTransformFeedbacki_v;
    300 	m_gl_getTransformFeedbacki64_v = (GetTransformFeedbacki64_v_ProcAddress)gl.getTransformFeedbacki64_v;
    301 
    302 	if ((DE_NULL == m_gl_getTransformFeedbackiv) || (DE_NULL == m_gl_getTransformFeedbacki_v) ||
    303 		(DE_NULL == m_gl_getTransformFeedbacki64_v))
    304 	{
    305 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Function pointers are set to NULL values."
    306 											<< tcu::TestLog::EndMessage;
    307 
    308 		throw 0;
    309 	}
    310 
    311 	/* XFB object creation */
    312 	gl.createTransformFeedbacks(1, &m_xfb_dsa);
    313 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
    314 
    315 	/* Query limits. */
    316 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &m_xfb_indexed_binding_points_count);
    317 	GLU_EXPECT_NO_ERROR(gl.getError(), "glIntegerv have failed");
    318 }
    319 
    320 /** @brief Test default value of GL_TRANSFORM_FEEDBACK_BUFFER_BINDING.
    321  *
    322  *  @note The function may throw if unexpected error has occured.
    323  *
    324  *  @return True if test succeeded, false otherwise.
    325  */
    326 bool DefaultsTest::testBuffersBindingPoints()
    327 {
    328 	/* Shortcut for GL functionality */
    329 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    330 
    331 	/* Check default binding points value. */
    332 	for (glw::GLint i = 0; i < m_xfb_indexed_binding_points_count; ++i)
    333 	{
    334 		glw::GLint buffer_binding = -1;
    335 
    336 		m_gl_getTransformFeedbacki_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, i, &buffer_binding);
    337 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");
    338 
    339 		if (-1 == buffer_binding)
    340 		{
    341 			m_context.getTestContext().getLog()
    342 				<< tcu::TestLog::Message
    343 				<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING has not returned "
    344 				   "anything and error has not been generated."
    345 				<< tcu::TestLog::EndMessage;
    346 
    347 			return false;
    348 		}
    349 		else
    350 		{
    351 			if (0 != buffer_binding)
    352 			{
    353 				m_context.getTestContext().getLog()
    354 					<< tcu::TestLog::Message
    355 					<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING has returned "
    356 					<< buffer_binding << ", however 0 is expected." << tcu::TestLog::EndMessage;
    357 
    358 				return false;
    359 			}
    360 		}
    361 	}
    362 
    363 	return true;
    364 }
    365 
    366 /** @brief Test default values of GL_TRANSFORM_FEEDBACK_START and GL_TRANSFORM_FEEDBACK_SIZE.
    367  *
    368  *  @note The function may throw if unexpected error has occured.
    369  *
    370  *  @return True if test succeeded, false otherwise.
    371  */
    372 bool DefaultsTest::testBuffersDimensions()
    373 {
    374 	/* Shortcut for GL functionality */
    375 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    376 
    377 	/* Check default buffers' start value. */
    378 	for (glw::GLint i = 0; i < m_xfb_indexed_binding_points_count; ++i)
    379 	{
    380 		glw::GLint64 buffer_start = -1;
    381 
    382 		m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_START, i, &buffer_start);
    383 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");
    384 
    385 		if (-1 == buffer_start)
    386 		{
    387 			m_context.getTestContext().getLog()
    388 				<< tcu::TestLog::Message
    389 				<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START has not returned "
    390 				   "anything and error has not been generated."
    391 				<< tcu::TestLog::EndMessage;
    392 
    393 			return false;
    394 		}
    395 		else
    396 		{
    397 			if (0 != buffer_start)
    398 			{
    399 				m_context.getTestContext().getLog()
    400 					<< tcu::TestLog::Message
    401 					<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START has returned "
    402 					<< buffer_start << ", however 0 is expected." << tcu::TestLog::EndMessage;
    403 
    404 				return false;
    405 			}
    406 		}
    407 	}
    408 
    409 	/** @brief Check default buffers' size value.
    410 	 *
    411 	 *  @note The function may throw if unexpected error has occured.
    412 	 */
    413 	for (glw::GLint i = 0; i < m_xfb_indexed_binding_points_count; ++i)
    414 	{
    415 		glw::GLint64 buffer_size = -1;
    416 
    417 		m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, i, &buffer_size);
    418 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");
    419 
    420 		if (-1 == buffer_size)
    421 		{
    422 			m_context.getTestContext().getLog()
    423 				<< tcu::TestLog::Message
    424 				<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE has not returned "
    425 				   "anything and error has not been generated."
    426 				<< tcu::TestLog::EndMessage;
    427 
    428 			return false;
    429 		}
    430 		else
    431 		{
    432 			if (0 != buffer_size)
    433 			{
    434 				m_context.getTestContext().getLog()
    435 					<< tcu::TestLog::Message
    436 					<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE has returned "
    437 					<< buffer_size << ", however 0 is expected." << tcu::TestLog::EndMessage;
    438 
    439 				return false;
    440 			}
    441 		}
    442 	}
    443 
    444 	return true;
    445 }
    446 
    447 /** @brief Test default value of GL_TRANSFORM_FEEDBACK_ACTIVE.
    448  *
    449  *  @return True if test succeeded, false otherwise.
    450  */
    451 bool DefaultsTest::testActive()
    452 {
    453 	/* Check that it is not active. */
    454 	glw::GLint is_active = -1;
    455 	m_gl_getTransformFeedbackiv(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_ACTIVE, &is_active);
    456 
    457 	if (-1 == is_active)
    458 	{
    459 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    460 											<< "glGetTransformFeedbackiv with parameter GL_TRANSFORM_FEEDBACK_ACTIVE "
    461 											   "has not returned anything and error has not been generated."
    462 											<< tcu::TestLog::EndMessage;
    463 
    464 		return false;
    465 	}
    466 	else
    467 	{
    468 		if (0 != is_active)
    469 		{
    470 			m_context.getTestContext().getLog()
    471 				<< tcu::TestLog::Message
    472 				<< "glGetTransformFeedbackiv with parameter GL_TRANSFORM_FEEDBACK_ACTIVE has returned " << is_active
    473 				<< ", however FALSE is expected." << tcu::TestLog::EndMessage;
    474 
    475 			return false;
    476 		}
    477 	}
    478 
    479 	return true;
    480 }
    481 
    482 /** @brief Test default value of GL_TRANSFORM_FEEDBACK_PAUSED.
    483  *
    484  *  @return True if test succeeded, false otherwise.
    485  */
    486 bool DefaultsTest::testPaused()
    487 {
    488 	/* Check that it is not paused. */
    489 	glw::GLint is_paused = -1;
    490 	m_gl_getTransformFeedbackiv(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_PAUSED, &is_paused);
    491 
    492 	if (-1 == is_paused)
    493 	{
    494 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    495 											<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_PAUSED "
    496 											   "has not returned anything and error has not been generated."
    497 											<< tcu::TestLog::EndMessage;
    498 
    499 		return false;
    500 	}
    501 	else
    502 	{
    503 		if (0 != is_paused)
    504 		{
    505 			m_context.getTestContext().getLog()
    506 				<< tcu::TestLog::Message
    507 				<< "glGetTransformFeedbackiv with parameter GL_TRANSFORM_FEEDBACK_PAUSED has returned " << is_paused
    508 				<< ", however FALSE is expected." << tcu::TestLog::EndMessage;
    509 
    510 			return false;
    511 		}
    512 	}
    513 
    514 	return true;
    515 }
    516 
    517 /** @brief Release GL objects.
    518  */
    519 void DefaultsTest::clean()
    520 {
    521 	/* Shortcut for GL functionality */
    522 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    523 
    524 	if (m_xfb_dsa)
    525 	{
    526 		gl.deleteTransformFeedbacks(1, &m_xfb_dsa);
    527 
    528 		m_xfb_dsa = 0;
    529 	}
    530 }
    531 
    532 /******************************** Buffers Test Implementation   ********************************/
    533 
    534 /** @brief Buffers Test constructor.
    535  *
    536  *  @param [in] context     OpenGL context.
    537  */
    538 BuffersTest::BuffersTest(deqp::Context& context)
    539 	: deqp::TestCase(context, "xfb_buffers", "Transform Feedback Buffers Test")
    540 	, m_gl_getTransformFeedbacki_v(DE_NULL)
    541 	, m_gl_getTransformFeedbacki64_v(DE_NULL)
    542 	, m_gl_TransformFeedbackBufferBase(DE_NULL)
    543 	, m_gl_TransformFeedbackBufferRange(DE_NULL)
    544 	, m_xfb_dsa(0)
    545 	, m_bo_a(0)
    546 	, m_bo_b(0)
    547 {
    548 	/* Intentionally left blank. */
    549 }
    550 
    551 /** @brief Iterate Buffers Test cases.
    552  *
    553  *  @return Iteration result.
    554  */
    555 tcu::TestNode::IterateResult BuffersTest::iterate()
    556 {
    557 	/* Get context setup. */
    558 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    559 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
    560 
    561 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    562 	{
    563 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
    564 
    565 		return STOP;
    566 	}
    567 
    568 	/* Running tests. */
    569 	bool is_ok	= true;
    570 	bool is_error = false;
    571 
    572 	try
    573 	{
    574 		/* Prepare function pointers, transform feedback and buffer objects. */
    575 		prepareObjects();
    576 
    577 		/* Setup transform feedback object binding points with buffer objects. */
    578 		is_ok = prepareTestSetup();
    579 
    580 		/* Continue only if test setup succeeded */
    581 		if (is_ok)
    582 		{
    583 			is_ok &= testBindingPoint(0, m_bo_a, "glTransformFeedbackBufferBase");
    584 			is_ok &= testBindingPoint(1, m_bo_b, "glTransformFeedbackBufferRange");
    585 			is_ok &= testBindingPoint(2, m_bo_b, "glTransformFeedbackBufferRange");
    586 
    587 			is_ok &= testStart(0, 0, "glTransformFeedbackBufferBase");
    588 			is_ok &= testStart(1, 0, "glTransformFeedbackBufferRange");
    589 			is_ok &= testStart(2, s_bo_size / 2, "glTransformFeedbackBufferRange");
    590 
    591 			is_ok &= testSize(0, 0, "glTransformFeedbackBufferBase");
    592 			is_ok &= testSize(1, s_bo_size / 2, "glTransformFeedbackBufferRange");
    593 			is_ok &= testSize(2, s_bo_size / 2, "glTransformFeedbackBufferRange");
    594 		}
    595 	}
    596 	catch (...)
    597 	{
    598 		is_ok	= false;
    599 		is_error = true;
    600 	}
    601 
    602 	/* Clean up. */
    603 	clean();
    604 
    605 	/* Result's setup. */
    606 	if (is_ok)
    607 	{
    608 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    609 	}
    610 	else
    611 	{
    612 		if (is_error)
    613 		{
    614 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
    615 		}
    616 		else
    617 		{
    618 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    619 		}
    620 	}
    621 
    622 	return STOP;
    623 }
    624 
    625 /** @brief Create XFB amd BO objects. Setup function pointers.
    626  *
    627  *  @note The function may throw if unexpected error has occured.
    628  */
    629 void BuffersTest::prepareObjects()
    630 {
    631 	/* Shortcut for GL functionality */
    632 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    633 
    634 	/* Fetching function pointers. */
    635 	m_gl_getTransformFeedbacki_v	  = (GetTransformFeedbacki_v_ProcAddress)gl.getTransformFeedbacki_v;
    636 	m_gl_getTransformFeedbacki64_v	= (GetTransformFeedbacki64_v_ProcAddress)gl.getTransformFeedbacki64_v;
    637 	m_gl_TransformFeedbackBufferBase  = (TransformFeedbackBufferBase_ProcAddress)gl.transformFeedbackBufferBase;
    638 	m_gl_TransformFeedbackBufferRange = (TransformFeedbackBufferRange_ProcAddress)gl.transformFeedbackBufferRange;
    639 
    640 	if ((DE_NULL == m_gl_getTransformFeedbacki_v) || (DE_NULL == m_gl_getTransformFeedbacki64_v) ||
    641 		(DE_NULL == m_gl_TransformFeedbackBufferBase) || (DE_NULL == m_gl_TransformFeedbackBufferRange))
    642 	{
    643 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Function pointers are set to NULL values."
    644 											<< tcu::TestLog::EndMessage;
    645 
    646 		throw 0;
    647 	}
    648 
    649 	/** @brief XFB object creation */
    650 	gl.createTransformFeedbacks(1, &m_xfb_dsa);
    651 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
    652 
    653 	/* Buffer Objects creation. */
    654 	gl.genBuffers(1, &m_bo_a);
    655 	gl.genBuffers(1, &m_bo_b);
    656 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");
    657 
    658 	if ((0 == m_bo_a) || (0 == m_bo_b))
    659 	{
    660 		m_context.getTestContext().getLog() << tcu::TestLog::Message
    661 											<< "Buffer object has not been generated and no error has been triggered."
    662 											<< tcu::TestLog::EndMessage;
    663 
    664 		throw 0;
    665 	}
    666 
    667 	/* First buffer memory allocation. */
    668 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_a);
    669 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");
    670 
    671 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, NULL, GL_DYNAMIC_COPY);
    672 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed");
    673 
    674 	/* Sainty check of buffer size */
    675 	glw::GLint allocated_size = -1;
    676 
    677 	gl.getBufferParameteriv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_BUFFER_SIZE, &allocated_size);
    678 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferParameteriv have failed");
    679 
    680 	if (allocated_size != (glw::GLint)s_bo_size)
    681 	{
    682 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Buffer allocation failed."
    683 											<< tcu::TestLog::EndMessage;
    684 
    685 		throw 0;
    686 	}
    687 
    688 	/* Second buffer memory allocation. */
    689 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_b);
    690 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");
    691 
    692 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, NULL, GL_DYNAMIC_COPY);
    693 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed");
    694 
    695 	/* Sainty check of buffer size */
    696 	allocated_size = -1;
    697 
    698 	gl.getBufferParameteriv(GL_TRANSFORM_FEEDBACK_BUFFER, GL_BUFFER_SIZE, &allocated_size);
    699 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBufferParameteriv have failed");
    700 
    701 	if (allocated_size != (glw::GLint)s_bo_size)
    702 	{
    703 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Buffer allocation failed."
    704 											<< tcu::TestLog::EndMessage;
    705 
    706 		throw 0;
    707 	}
    708 
    709 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
    710 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffers have failed");
    711 }
    712 
    713 /** @brief Setup indexed buffer binding points in the xfb object using
    714  *         glTransformFeedbackBufferBase and glTransformFeedbackBufferRange
    715  *         functions.
    716  *
    717  *  @return True if setup succeeded, false otherwise (functions triggered errors).
    718  */
    719 bool BuffersTest::prepareTestSetup()
    720 {
    721 	/* Shortcut for GL functionality */
    722 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    723 
    724 	/* Bind Buffer Object to first indexed binding point. */
    725 	m_gl_TransformFeedbackBufferBase(m_xfb_dsa, 0, m_bo_a);
    726 
    727 	/* Check errors. */
    728 	glw::GLenum error_value = gl.getError();
    729 
    730 	if (GL_NONE != error_value)
    731 	{
    732 		m_context.getTestContext().getLog()
    733 			<< tcu::TestLog::Message << "glTransformFeedbackBufferBase has generated unexpected error ("
    734 			<< glu::getErrorStr(error_value) << "). Test Failed." << tcu::TestLog::EndMessage;
    735 
    736 		return false;
    737 	}
    738 
    739 	/* Bind Buffer Object to second and third indexed binding point. */
    740 	m_gl_TransformFeedbackBufferRange(m_xfb_dsa, 1, m_bo_b, 0, s_bo_size / 2);
    741 	m_gl_TransformFeedbackBufferRange(m_xfb_dsa, 2, m_bo_b, s_bo_size / 2, s_bo_size / 2);
    742 
    743 	/* Check errors. */
    744 	error_value = gl.getError();
    745 
    746 	if (GL_NONE != error_value)
    747 	{
    748 		m_context.getTestContext().getLog()
    749 			<< tcu::TestLog::Message << "glTransformFeedbackBufferRange has generated unexpected error ("
    750 			<< glu::getErrorStr(error_value) << "). Test Failed." << tcu::TestLog::EndMessage;
    751 
    752 		return false;
    753 	}
    754 
    755 	return true;
    756 }
    757 
    758 /** @brief Test that xfb object's binding point #<index> has <expected_value>.
    759  *
    760  *  @param [in] index                   Tested index point.
    761  *  @param [in] expected_value          Value to be expected (buffer name).
    762  *  @param [in] tested_function_name    Name of function which this function is going to test
    763  *                                      (glTransformFeedbackBufferBase or glTransformFeedbackBufferRange)
    764  *                                      for logging purposes.
    765  *
    766  *  @note The function may throw if unexpected error has occured.
    767  *
    768  *  @return True if test succeeded, false otherwise.
    769  */
    770 bool BuffersTest::testBindingPoint(glw::GLuint const index, glw::GLint const expected_value,
    771 								   glw::GLchar const* const tested_function_name)
    772 {
    773 	/* Shortcut for GL functionality */
    774 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    775 
    776 	/* Check default binding points value. */
    777 	glw::GLint buffer_binding = -1;
    778 
    779 	m_gl_getTransformFeedbacki_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, index, &buffer_binding);
    780 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");
    781 
    782 	if (-1 == buffer_binding)
    783 	{
    784 		m_context.getTestContext().getLog()
    785 			<< tcu::TestLog::Message << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING "
    786 										"has not returned anything and error has not been generated."
    787 			<< tcu::TestLog::EndMessage;
    788 
    789 		return false;
    790 	}
    791 	else
    792 	{
    793 		if (expected_value != buffer_binding)
    794 		{
    795 			m_context.getTestContext().getLog()
    796 				<< tcu::TestLog::Message
    797 				<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_BINDING has returned "
    798 				<< buffer_binding << ", however " << expected_value << " is expected. As a consequence function "
    799 				<< tested_function_name << " have failed to setup proper value." << tcu::TestLog::EndMessage;
    800 
    801 			return false;
    802 		}
    803 	}
    804 
    805 	return true;
    806 }
    807 
    808 /** @brief Test that buffer object at xfb object's binding point #<index> has starting offset set to the <expected_value>.
    809  *
    810  *  @param [in] index                   Tested index point.
    811  *  @param [in] expected_value          Value to be expected (starting offset).
    812  *  @param [in] tested_function_name    Name of function which this function is going to test
    813  *                                      (glTransformFeedbackBufferBase or glTransformFeedbackBufferRange)
    814  *                                      for logging purposes.
    815  *
    816  *  @note The function may throw if unexpected error has occured.
    817  *
    818  *  @return True if test succeeded, false otherwise.
    819  */
    820 bool BuffersTest::testStart(glw::GLuint const index, glw::GLint const expected_value,
    821 							glw::GLchar const* const tested_function_name)
    822 {
    823 	/* Shortcut for GL functionality */
    824 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    825 
    826 	/* Check default buffers' start value. */
    827 	glw::GLint64 buffer_start = -1;
    828 
    829 	m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_START, index, &buffer_start);
    830 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");
    831 
    832 	/* Checking results and errors. */
    833 	if (-1 == buffer_start)
    834 	{
    835 		m_context.getTestContext().getLog()
    836 			<< tcu::TestLog::Message << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START "
    837 										"has not returned anything and error has not been generated."
    838 			<< tcu::TestLog::EndMessage;
    839 
    840 		return false;
    841 	}
    842 	else
    843 	{
    844 		if (expected_value != buffer_start)
    845 		{
    846 			m_context.getTestContext().getLog()
    847 				<< tcu::TestLog::Message
    848 				<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_START has returned "
    849 				<< buffer_start << ", however " << expected_value << " is expected. As a consequence function "
    850 				<< tested_function_name << " have failed to setup proper value." << tcu::TestLog::EndMessage;
    851 
    852 			return false;
    853 		}
    854 	}
    855 
    856 	return true;
    857 }
    858 
    859 /** @brief Test that buffer object at xfb object's binding point #<index> has size set to the <expected_value>.
    860  *
    861  *  @param [in] index                   Tested index point.
    862  *  @param [in] expected_value          Value to be expected (buffer's size).
    863  *  @param [in] tested_function_name    Name of function which this function is going to test
    864  *                                      (glTransformFeedbackBufferBase or glTransformFeedbackBufferRange)
    865  *                                      for logging purposes.
    866  *
    867  *  @note The function may throw if unexpected error has occured.
    868  *
    869  *  @return True if test succeeded, false otherwise.
    870  */
    871 bool BuffersTest::testSize(glw::GLuint const index, glw::GLint const expected_value,
    872 						   glw::GLchar const* const tested_function_name)
    873 {
    874 	/* Shortcut for GL functionality */
    875 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    876 
    877 	/* Check default buffer's size value. */
    878 	glw::GLint64 buffer_size = -1;
    879 
    880 	m_gl_getTransformFeedbacki64_v(m_xfb_dsa, GL_TRANSFORM_FEEDBACK_BUFFER_SIZE, index, &buffer_size);
    881 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbacki_v have failed");
    882 
    883 	/* Checking results and errors. */
    884 	if (-1 == buffer_size)
    885 	{
    886 		m_context.getTestContext().getLog()
    887 			<< tcu::TestLog::Message << "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE "
    888 										"has not returned anything and error has not been generated."
    889 			<< tcu::TestLog::EndMessage;
    890 
    891 		return false;
    892 	}
    893 	else
    894 	{
    895 		if (expected_value != buffer_size)
    896 		{
    897 			m_context.getTestContext().getLog()
    898 				<< tcu::TestLog::Message
    899 				<< "glGetTransformFeedbacki_v with parameter GL_TRANSFORM_FEEDBACK_BUFFER_SIZE has returned "
    900 				<< buffer_size << ", however " << expected_value << " is expected. As a consequence function "
    901 				<< tested_function_name << " have failed to setup proper value." << tcu::TestLog::EndMessage;
    902 
    903 			return false;
    904 		}
    905 	}
    906 
    907 	return true;
    908 }
    909 
    910 /** @brief Clean al GL objects
    911  */
    912 void BuffersTest::clean()
    913 {
    914 	/* Shortcut for GL functionality */
    915 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    916 
    917 	/* Release transform feedback object. */
    918 	if (m_xfb_dsa)
    919 	{
    920 		gl.deleteTransformFeedbacks(1, &m_xfb_dsa);
    921 
    922 		m_xfb_dsa = 0;
    923 	}
    924 
    925 	/* Release buffer objects. */
    926 	if (m_bo_a)
    927 	{
    928 		gl.deleteBuffers(1, &m_bo_a);
    929 
    930 		m_bo_a = 0;
    931 	}
    932 
    933 	if (m_bo_b)
    934 	{
    935 		gl.deleteBuffers(1, &m_bo_b);
    936 
    937 		m_bo_b = 0;
    938 	}
    939 }
    940 
    941 /** @brief Buffer Object Size */
    942 const glw::GLuint BuffersTest::s_bo_size = 512;
    943 
    944 /******************************** Errors Test Implementation   ********************************/
    945 
    946 /** @brief Errors Test constructor.
    947  *
    948  *  @param [in] context     OpenGL context.
    949  */
    950 ErrorsTest::ErrorsTest(deqp::Context& context)
    951 	: deqp::TestCase(context, "xfb_errors", "Transform Feedback Errors Test")
    952 	, m_gl_getTransformFeedbackiv(DE_NULL)
    953 	, m_gl_getTransformFeedbacki_v(DE_NULL)
    954 	, m_gl_getTransformFeedbacki64_v(DE_NULL)
    955 {
    956 	/* Intentionally left blank. */
    957 }
    958 
    959 /** @brief Iterate Errors Test cases.
    960  *
    961  *  @return Iteration result.
    962  */
    963 tcu::TestNode::IterateResult ErrorsTest::iterate()
    964 {
    965 	/* Get context setup. */
    966 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    967 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
    968 
    969 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    970 	{
    971 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
    972 
    973 		return STOP;
    974 	}
    975 
    976 	/* Running tests. */
    977 	bool is_ok	= true;
    978 	bool is_error = false;
    979 
    980 	try
    981 	{
    982 		prepareFunctionPointers();
    983 
    984 		is_ok &= testCreateTransformFeedbacksForInvalidNumberOfObjects();
    985 		cleanErrors();
    986 
    987 		is_ok &= testQueriesForInvalidNameOfObject();
    988 		cleanErrors();
    989 
    990 		is_ok &= testGetTransformFeedbackivQueryForInvalidParameterName();
    991 		cleanErrors();
    992 
    993 		is_ok &= testGetTransformFeedbacki_vQueryForInvalidParameterName();
    994 		cleanErrors();
    995 
    996 		is_ok &= testGetTransformFeedbacki64_vQueryForInvalidParameterName();
    997 		cleanErrors();
    998 
    999 		is_ok &= testIndexedQueriesForInvalidBindingPoint();
   1000 		cleanErrors();
   1001 	}
   1002 	catch (...)
   1003 	{
   1004 		is_ok	= false;
   1005 		is_error = true;
   1006 	}
   1007 
   1008 	/* Result's setup. */
   1009 	if (is_ok)
   1010 	{
   1011 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1012 	}
   1013 	else
   1014 	{
   1015 		if (is_error)
   1016 		{
   1017 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   1018 		}
   1019 		else
   1020 		{
   1021 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1022 		}
   1023 	}
   1024 
   1025 	return STOP;
   1026 }
   1027 
   1028 /** @brief Fetch GL function pointers.
   1029  *
   1030  *  @note The function may throw if unexpected error has occured.
   1031  */
   1032 void ErrorsTest::prepareFunctionPointers()
   1033 {
   1034 	/* Shortcut for GL functionality */
   1035 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1036 
   1037 	/* Fetching function pointers. */
   1038 	m_gl_getTransformFeedbackiv	= (GetTransformFeedbackiv_ProcAddress)gl.getTransformFeedbackiv;
   1039 	m_gl_getTransformFeedbacki_v   = (GetTransformFeedbacki_v_ProcAddress)gl.getTransformFeedbacki_v;
   1040 	m_gl_getTransformFeedbacki64_v = (GetTransformFeedbacki64_v_ProcAddress)gl.getTransformFeedbacki64_v;
   1041 
   1042 	if ((DE_NULL == m_gl_getTransformFeedbackiv) || (DE_NULL == m_gl_getTransformFeedbacki_v) ||
   1043 		(DE_NULL == m_gl_getTransformFeedbacki64_v))
   1044 	{
   1045 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Function pointers are set to NULL values."
   1046 											<< tcu::TestLog::EndMessage;
   1047 
   1048 		throw 0;
   1049 	}
   1050 }
   1051 
   1052 /** @brief Sanity clean-up of GL errors.
   1053  *
   1054  *  @note This function is to only make sure that failing test will not affect other tests.
   1055  */
   1056 void ErrorsTest::cleanErrors()
   1057 {
   1058 	/* Shortcut for GL functionality */
   1059 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1060 
   1061 	/* Cleaning errors. */
   1062 	while (GL_NO_ERROR != gl.getError())
   1063 		;
   1064 }
   1065 
   1066 /** @brief Test Creation of Transform Feedbacks using Invalid Number Of Objects
   1067  *
   1068  *  @note Test checks that CreateTransformFeedbacks generates INVALID_VALUE error if
   1069  *        number of transform feedback objects to create is negative.
   1070  *
   1071  *  @return true if test succeded, false otherwise.
   1072  */
   1073 bool ErrorsTest::testCreateTransformFeedbacksForInvalidNumberOfObjects()
   1074 {
   1075 	/* Shortcut for GL functionality */
   1076 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1077 
   1078 	glw::GLuint xfbs = 314159;
   1079 
   1080 	gl.createTransformFeedbacks(-1 /* invalid count */, &xfbs);
   1081 
   1082 	glw::GLenum error = gl.getError();
   1083 
   1084 	if (GL_INVALID_VALUE != error)
   1085 	{
   1086 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1087 											<< "glCreateTransformFeedbacks called with negative number of objects had "
   1088 											   "been expected to generate GL_INVALID_VALUE. However, "
   1089 											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
   1090 
   1091 		return false;
   1092 	}
   1093 
   1094 	if (314159 != xfbs)
   1095 	{
   1096 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1097 											<< "glCreateTransformFeedbacks called with negative number of objects had "
   1098 											   "been expected not to change the given buffer."
   1099 											<< tcu::TestLog::EndMessage;
   1100 
   1101 		return false;
   1102 	}
   1103 
   1104 	return true;
   1105 }
   1106 
   1107 /** @brief Test Direct State Access queries with invalid object name
   1108  *
   1109  *  @note Test checks that GetTransformFeedbackiv, GetTransformFeedbacki_v and
   1110  *        GetTransformFeedbacki64_v generate INVALID_OPERATION error if xfb is not
   1111  *        zero or the name of an existing transform feedback object.
   1112  *
   1113  *  @return true if test succeded, false otherwise.
   1114  */
   1115 bool ErrorsTest::testQueriesForInvalidNameOfObject()
   1116 {
   1117 	/* Shortcut for GL functionality */
   1118 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1119 
   1120 	/* Generating not a-TransformFeedback name. */
   1121 	glw::GLuint invalid_name = 0;
   1122 
   1123 	while (GL_TRUE == gl.isTransformFeedback(++invalid_name))
   1124 		;
   1125 
   1126 	/* Dummy storage. */
   1127 	glw::GLint   buffer   = 314159;
   1128 	glw::GLint64 buffer64 = 314159;
   1129 
   1130 	/* Error variable. */
   1131 	glw::GLenum error = 0;
   1132 
   1133 	/* Test of GetTransformFeedbackiv. */
   1134 	m_gl_getTransformFeedbackiv(invalid_name, GL_TRANSFORM_FEEDBACK_PAUSED, &buffer);
   1135 
   1136 	if (GL_INVALID_OPERATION != (error = gl.getError()))
   1137 	{
   1138 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1139 											<< "glGetTransformFeedbackiv called with invalid object name had been "
   1140 											   "expected to generate GL_INVALID_OPERATION. However, "
   1141 											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
   1142 
   1143 		return false;
   1144 	}
   1145 
   1146 	if (314159 != buffer)
   1147 	{
   1148 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1149 											<< "glGetTransformFeedbackiv called with invalid object name had been "
   1150 											   "expected not to change the given buffer."
   1151 											<< tcu::TestLog::EndMessage;
   1152 
   1153 		return false;
   1154 	}
   1155 
   1156 	while (GL_NO_ERROR != (error = gl.getError()))
   1157 	{
   1158 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1159 											<< "Warning! glGetTransformFeedbackiv called with invalid object name has "
   1160 											   "generated more than one error, The next error was  "
   1161 											<< glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
   1162 	}
   1163 
   1164 	/* Test of GetTransformFeedbacki_v. */
   1165 	m_gl_getTransformFeedbacki_v(invalid_name, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, 0, &buffer);
   1166 
   1167 	if (GL_INVALID_OPERATION != (error = gl.getError()))
   1168 	{
   1169 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1170 											<< "glGetTransformFeedbacki_v called with invalid object name had been "
   1171 											   "expected to generate GL_INVALID_OPERATION. However, "
   1172 											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
   1173 
   1174 		return false;
   1175 	}
   1176 
   1177 	if (314159 != buffer)
   1178 	{
   1179 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1180 											<< "glGetTransformFeedbacki_v called with invalid object name had been "
   1181 											   "expected not to change the given buffer."
   1182 											<< tcu::TestLog::EndMessage;
   1183 
   1184 		return false;
   1185 	}
   1186 
   1187 	while (GL_NO_ERROR != (error = gl.getError()))
   1188 	{
   1189 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1190 											<< "Warning! glGetTransformFeedbacki_v called with invalid object name has "
   1191 											   "unexpectedly generated more than one error, The next error was  "
   1192 											<< glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
   1193 	}
   1194 
   1195 	/* Test of GetTransformFeedbacki64_v. */
   1196 	m_gl_getTransformFeedbacki64_v(invalid_name, GL_TRANSFORM_FEEDBACK_BUFFER_START, 0, &buffer64);
   1197 
   1198 	if (GL_INVALID_OPERATION != (error = gl.getError()))
   1199 	{
   1200 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1201 											<< "glGetTransformFeedbacki64_v called with invalid object name had been "
   1202 											   "expected to generate GL_INVALID_OPERATION. However, "
   1203 											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
   1204 
   1205 		return false;
   1206 	}
   1207 
   1208 	if (314159 != buffer64)
   1209 	{
   1210 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1211 											<< "glGetTransformFeedbacki64_v called with invalid object name had been "
   1212 											   "expected not to change the given buffer."
   1213 											<< tcu::TestLog::EndMessage;
   1214 
   1215 		return false;
   1216 	}
   1217 
   1218 	while (GL_NO_ERROR != (error = gl.getError()))
   1219 	{
   1220 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1221 											<< "Warning! glGetTransformFeedbacki64_v called with invalid object name "
   1222 											   "has unexpectedly generated more than one error, The next error was  "
   1223 											<< glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
   1224 	}
   1225 
   1226 	return true;
   1227 }
   1228 
   1229 /** @brief Test Direct State Access queries with invalid parameter name
   1230  *
   1231  *  @note Test checks that GetTransformFeedbackiv generates INVALID_ENUM error if pname
   1232  *        is not TRANSFORM_FEEDBACK_PAUSED or TRANSFORM_FEEDBACK_ACTIVE.
   1233  *
   1234  *  @note The function may throw if unexpected error has occured.
   1235  *
   1236  *  @return true if test succeded, false otherwise.
   1237  */
   1238 bool ErrorsTest::testGetTransformFeedbackivQueryForInvalidParameterName()
   1239 {
   1240 	/* Shortcut for GL functionality */
   1241 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1242 
   1243 	/* Creating XFB object. */
   1244 	glw::GLuint xfb = 0;
   1245 
   1246 	gl.createTransformFeedbacks(1, &xfb);
   1247 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
   1248 
   1249 	/* Generating invalid parameter name. */
   1250 	glw::GLuint invalid_parameter_name = 0;
   1251 
   1252 	/* Dummy storage. */
   1253 	glw::GLint buffer = 314159;
   1254 
   1255 	/* Error variable. */
   1256 	glw::GLenum error = 0;
   1257 
   1258 	/* Default result. */
   1259 	bool is_ok = true;
   1260 
   1261 	/* Test of GetTransformFeedbackiv. */
   1262 	m_gl_getTransformFeedbackiv(xfb, invalid_parameter_name, &buffer);
   1263 
   1264 	if (GL_INVALID_ENUM != (error = gl.getError()))
   1265 	{
   1266 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1267 											<< "glGetTransformFeedbackiv called with invalid parameter name had been "
   1268 											   "expected to generate GL_INVALID_ENUM. However, "
   1269 											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
   1270 
   1271 		is_ok = false;
   1272 	}
   1273 
   1274 	if (314159 != buffer)
   1275 	{
   1276 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1277 											<< "glGetTransformFeedbackiv called with invalid parameter name had been "
   1278 											   "expected not to change the given buffer."
   1279 											<< tcu::TestLog::EndMessage;
   1280 
   1281 		is_ok = false;
   1282 	}
   1283 
   1284 	while (GL_NO_ERROR != (error = gl.getError()))
   1285 	{
   1286 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1287 											<< "Warning! glGetTransformFeedbackiv called with invalid parameter name "
   1288 											   "has generated more than one error, The next error was  "
   1289 											<< glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
   1290 	}
   1291 
   1292 	/* Clean-up. */
   1293 	gl.deleteTransformFeedbacks(1, &xfb);
   1294 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed");
   1295 
   1296 	return is_ok;
   1297 }
   1298 
   1299 /** @brief Test Direct State Access indexed integer query with invalid parameter name
   1300  *
   1301  *  @note Test checks that GetTransformFeedbacki_v generates INVALID_ENUM error if pname
   1302  *        is not TRANSFORM_FEEDBACK_BUFFER_BINDING.
   1303  *
   1304  *  @note The function may throw if unexpected error has occured.
   1305  *
   1306  *  @return true if test succeded, false otherwise.
   1307  */
   1308 bool ErrorsTest::testGetTransformFeedbacki_vQueryForInvalidParameterName()
   1309 {
   1310 	/* Shortcut for GL functionality */
   1311 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1312 
   1313 	/* Creating XFB object. */
   1314 	glw::GLuint xfb = 0;
   1315 
   1316 	gl.createTransformFeedbacks(1, &xfb);
   1317 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
   1318 
   1319 	/* Generating invalid parameter name. */
   1320 	glw::GLuint invalid_parameter_name = 0;
   1321 
   1322 	/* Dummy storage. */
   1323 	glw::GLint buffer = 314159;
   1324 
   1325 	/* Error variable. */
   1326 	glw::GLenum error = 0;
   1327 
   1328 	/* Default result. */
   1329 	bool is_ok = true;
   1330 
   1331 	/* Test of GetTransformFeedbackiv. */
   1332 	m_gl_getTransformFeedbacki_v(xfb, invalid_parameter_name, 0, &buffer);
   1333 
   1334 	if (GL_INVALID_ENUM != (error = gl.getError()))
   1335 	{
   1336 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1337 											<< "glGetTransformFeedbacki_v called with invalid parameter name had been "
   1338 											   "expected to generate GL_INVALID_ENUM. However, "
   1339 											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
   1340 
   1341 		is_ok = false;
   1342 	}
   1343 
   1344 	if (314159 != buffer)
   1345 	{
   1346 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1347 											<< "glGetTransformFeedbacki_v called with invalid parameter name had been "
   1348 											   "expected not to change the given buffer."
   1349 											<< tcu::TestLog::EndMessage;
   1350 
   1351 		is_ok = false;
   1352 	}
   1353 
   1354 	while (GL_NO_ERROR != (error = gl.getError()))
   1355 	{
   1356 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1357 											<< "Warning! glGetTransformFeedbacki_v called with invalid parameter name "
   1358 											   "has generated more than one error, The next error was  "
   1359 											<< glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
   1360 	}
   1361 
   1362 	/* Clean-up. */
   1363 	gl.deleteTransformFeedbacks(1, &xfb);
   1364 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed");
   1365 
   1366 	return is_ok;
   1367 }
   1368 
   1369 /** @brief Test Direct State Access indexed 64 bit integer query with invalid parameter name
   1370  *
   1371  *  @note Test checks that GetTransformFeedbacki64_v generates INVALID_ENUM error if
   1372  *        pname is not TRANSFORM_FEEDBACK_BUFFER_START or
   1373  *        TRANSFORM_FEEDBACK_BUFFER_SIZE.
   1374  *
   1375  *  @note The function may throw if unexpected error has occured.
   1376  *
   1377  *  @return true if test succeded, false otherwise.
   1378  */
   1379 bool ErrorsTest::testGetTransformFeedbacki64_vQueryForInvalidParameterName()
   1380 {
   1381 	/* Shortcut for GL functionality */
   1382 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1383 
   1384 	/* Creating XFB object. */
   1385 	glw::GLuint xfb = 0;
   1386 
   1387 	gl.createTransformFeedbacks(1, &xfb);
   1388 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
   1389 
   1390 	/* Generating invalid parameter name. */
   1391 	glw::GLuint invalid_parameter_name = 0;
   1392 
   1393 	/* Dummy storage. */
   1394 	glw::GLint64 buffer = 314159;
   1395 
   1396 	/* Error variable. */
   1397 	glw::GLenum error = 0;
   1398 
   1399 	/* Default result. */
   1400 	bool is_ok = true;
   1401 
   1402 	/* Test of GetTransformFeedbackiv. */
   1403 	m_gl_getTransformFeedbacki64_v(xfb, invalid_parameter_name, 0, &buffer);
   1404 
   1405 	if (GL_INVALID_ENUM != (error = gl.getError()))
   1406 	{
   1407 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1408 											<< "glGetTransformFeedbacki64_v called with invalid parameter name had "
   1409 											   "been expected to generate GL_INVALID_ENUM. However, "
   1410 											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
   1411 
   1412 		is_ok = false;
   1413 	}
   1414 
   1415 	if (314159 != buffer)
   1416 	{
   1417 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1418 											<< "glGetTransformFeedbacki64_v called with invalid parameter name had "
   1419 											   "been expected not to change the given buffer."
   1420 											<< tcu::TestLog::EndMessage;
   1421 
   1422 		is_ok = false;
   1423 	}
   1424 
   1425 	while (GL_NO_ERROR != (error = gl.getError()))
   1426 	{
   1427 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1428 											<< "Warning! glGetTransformFeedbacki64_v called with invalid parameter "
   1429 											   "name has generated more than one error, The next error was  "
   1430 											<< glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
   1431 	}
   1432 
   1433 	/* Clean-up. */
   1434 	gl.deleteTransformFeedbacks(1, &xfb);
   1435 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed");
   1436 
   1437 	return is_ok;
   1438 }
   1439 
   1440 /** @brief Test Direct State Access indexed queries with invalid index
   1441  *
   1442  *  @note Test checks that GetTransformFeedbacki_v and GetTransformFeedbacki64_v
   1443  *        generate INVALID_VALUE error by GetTransformFeedbacki_v and
   1444  *        GetTransformFeedbacki64_v if index is greater than or equal to the
   1445  *        number of binding points for transform feedback (the value of
   1446  *        MAX_TRANSFORM_FEEDBACK_BUFFERS).
   1447  *
   1448  *  @note The function may throw if unexpected error has occured.
   1449  *
   1450  *  @return true if test succeded, false otherwise.
   1451  */
   1452 bool ErrorsTest::testIndexedQueriesForInvalidBindingPoint()
   1453 {
   1454 	/* Shortcut for GL functionality */
   1455 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1456 
   1457 	/* Generating invalid index. */
   1458 	glw::GLint max_transform_feedback_buffers =
   1459 		4; /* Default limit is 4 - OpenGL 4.5 Core Specification, Table 23.72: Implementation Dependent Transform Feedback Limits. */
   1460 
   1461 	gl.getIntegerv(GL_MAX_TRANSFORM_FEEDBACK_BUFFERS, &max_transform_feedback_buffers);
   1462 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv have failed");
   1463 
   1464 	/* Creating XFB object. */
   1465 	glw::GLuint xfb = 0;
   1466 
   1467 	gl.createTransformFeedbacks(1, &xfb);
   1468 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
   1469 
   1470 	/* Dummy storage. */
   1471 	glw::GLint   buffer   = 314159;
   1472 	glw::GLint64 buffer64 = 314159;
   1473 
   1474 	/* Error variable. */
   1475 	glw::GLenum error = 0;
   1476 
   1477 	/* Default result. */
   1478 	bool is_ok = true;
   1479 
   1480 	/* Test of GetTransformFeedbacki_v. */
   1481 	m_gl_getTransformFeedbacki_v(xfb, GL_TRANSFORM_FEEDBACK_BUFFER_BINDING, max_transform_feedback_buffers, &buffer);
   1482 
   1483 	if (GL_INVALID_VALUE != (error = gl.getError()))
   1484 	{
   1485 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1486 											<< "glGetTransformFeedbacki_v called with invalid index had been expected "
   1487 											   "to generate GL_INVALID_VALUE. However, "
   1488 											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
   1489 
   1490 		is_ok = false;
   1491 	}
   1492 
   1493 	if (314159 != buffer)
   1494 	{
   1495 		m_context.getTestContext().getLog()
   1496 			<< tcu::TestLog::Message
   1497 			<< "glGetTransformFeedbacki_v called with invalid index had been expected not to change the given buffer."
   1498 			<< tcu::TestLog::EndMessage;
   1499 
   1500 		is_ok = false;
   1501 	}
   1502 
   1503 	while (GL_NO_ERROR != (error = gl.getError()))
   1504 	{
   1505 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1506 											<< "Warning! glGetTransformFeedbacki_v called with invalid index has "
   1507 											   "unexpectedly generated more than one error, The next error was  "
   1508 											<< glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
   1509 	}
   1510 
   1511 	/* Test of GetTransformFeedbacki64_v. */
   1512 	m_gl_getTransformFeedbacki64_v(xfb, GL_TRANSFORM_FEEDBACK_BUFFER_START, max_transform_feedback_buffers, &buffer64);
   1513 
   1514 	if (GL_INVALID_VALUE != (error = gl.getError()))
   1515 	{
   1516 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1517 											<< "glGetTransformFeedbacki64_v called with invalid index had been "
   1518 											   "expected to generate GL_INVALID_VALUE. However, "
   1519 											<< glu::getErrorStr(error) << " was captured." << tcu::TestLog::EndMessage;
   1520 
   1521 		is_ok = false;
   1522 	}
   1523 
   1524 	if (314159 != buffer64)
   1525 	{
   1526 		m_context.getTestContext().getLog()
   1527 			<< tcu::TestLog::Message
   1528 			<< "glGetTransformFeedbacki64_v called with invalid index had been expected not to change the given buffer."
   1529 			<< tcu::TestLog::EndMessage;
   1530 
   1531 		is_ok = false;
   1532 	}
   1533 
   1534 	while (GL_NO_ERROR != (error = gl.getError()))
   1535 	{
   1536 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1537 											<< "Warning! glGetTransformFeedbacki64_v called with invalid index has "
   1538 											   "unexpectedly generated more than one error, The next error was  "
   1539 											<< glu::getErrorStr(error) << "." << tcu::TestLog::EndMessage;
   1540 	}
   1541 
   1542 	/* Clean-up. */
   1543 	gl.deleteTransformFeedbacks(1, &xfb);
   1544 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTransformFeedbacks have failed");
   1545 
   1546 	return is_ok;
   1547 }
   1548 
   1549 /******************************** Functional Test Implementation   ********************************/
   1550 
   1551 /** @brief Functional Test constructor.
   1552  *
   1553  *  @param [in] context     OpenGL context.
   1554  */
   1555 FunctionalTest::FunctionalTest(deqp::Context& context)
   1556 	: deqp::TestCase(context, "xfb_functional", "Transform Feedback Functional Test")
   1557 	, m_gl_getTransformFeedbackiv(DE_NULL)
   1558 	, m_gl_TransformFeedbackBufferBase(DE_NULL)
   1559 	, m_xfb_dsa(0)
   1560 	, m_bo(0)
   1561 	, m_po(0)
   1562 	, m_vao(0)
   1563 {
   1564 	/* Intentionally left blank. */
   1565 }
   1566 
   1567 /** @brief Iterate Functional Test cases.
   1568  *
   1569  *  @return Iteration result.
   1570  */
   1571 tcu::TestNode::IterateResult FunctionalTest::iterate()
   1572 {
   1573 	/* Get context setup. */
   1574 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
   1575 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
   1576 
   1577 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
   1578 	{
   1579 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
   1580 
   1581 		return STOP;
   1582 	}
   1583 
   1584 	/* Running tests. */
   1585 	bool is_ok	= true;
   1586 	bool is_error = false;
   1587 
   1588 	try
   1589 	{
   1590 		prepareFunctionPointers();
   1591 		prepareTransformFeedback();
   1592 		prepareBuffer();
   1593 		prepareProgram();
   1594 		prepareVertexArrayObject();
   1595 
   1596 		is_ok &= draw();
   1597 		is_ok &= verifyBufferContent();
   1598 	}
   1599 	catch (...)
   1600 	{
   1601 		is_ok	= false;
   1602 		is_error = true;
   1603 	}
   1604 
   1605 	/* Releasing GL objects. */
   1606 	clean();
   1607 
   1608 	/* Result's setup. */
   1609 	if (is_ok)
   1610 	{
   1611 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1612 	}
   1613 	else
   1614 	{
   1615 		if (is_error)
   1616 		{
   1617 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   1618 		}
   1619 		else
   1620 		{
   1621 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1622 		}
   1623 	}
   1624 
   1625 	return STOP;
   1626 }
   1627 
   1628 /** @brief Get access pointers to GL functions.
   1629  *
   1630  *  @note The function may throw if unexpected error has occured.
   1631  */
   1632 void FunctionalTest::prepareFunctionPointers()
   1633 {
   1634 	/* Shortcut for GL functionality */
   1635 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1636 
   1637 	/* Fetching function pointers. */
   1638 	m_gl_getTransformFeedbackiv		 = (GetTransformFeedbackiv_ProcAddress)gl.getTransformFeedbackiv;
   1639 	m_gl_TransformFeedbackBufferBase = (TransformFeedbackBufferBase_ProcAddress)gl.transformFeedbackBufferBase;
   1640 
   1641 	if ((DE_NULL == m_gl_getTransformFeedbackiv) || (DE_NULL == m_gl_TransformFeedbackBufferBase))
   1642 	{
   1643 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Function pointers are set to NULL values."
   1644 											<< tcu::TestLog::EndMessage;
   1645 
   1646 		throw 0;
   1647 	}
   1648 }
   1649 
   1650 /** @brief Create transform feedback object using direct access function.
   1651  *
   1652  *  @note The function may throw if unexpected error has occured.
   1653  */
   1654 void FunctionalTest::prepareTransformFeedback()
   1655 {
   1656 	/* Shortcut for GL functionality */
   1657 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1658 
   1659 	/* XFB object creation. */
   1660 	gl.createTransformFeedbacks(1, &m_xfb_dsa);
   1661 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateTransformFeedbacks have failed");
   1662 }
   1663 
   1664 /** @brief Create buffer object and bind it to transform feedback object using direct access function.
   1665  *
   1666  *  @note The function may throw if unexpected error has occured.
   1667  */
   1668 void FunctionalTest::prepareBuffer()
   1669 {
   1670 	/* Shortcut for GL functionality */
   1671 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1672 
   1673 	/* Buffer creation and memory allocation. */
   1674 	gl.genBuffers(1, &m_bo);
   1675 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers have failed");
   1676 
   1677 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo);
   1678 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer have failed");
   1679 
   1680 	gl.bufferData(GL_TRANSFORM_FEEDBACK_BUFFER, s_bo_size, DE_NULL, GL_DYNAMIC_COPY);
   1681 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData have failed");
   1682 
   1683 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
   1684 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer have failed");
   1685 
   1686 	/* Bind buffer to xfb object (using direct state access function). */
   1687 	m_gl_TransformFeedbackBufferBase(m_xfb_dsa, 0, m_bo);
   1688 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackBufferBase have failed");
   1689 }
   1690 
   1691 /** @brief Build test's GLSL program.
   1692  *
   1693  *  @note The function may throw if unexpected error has occured.
   1694  */
   1695 void FunctionalTest::prepareProgram()
   1696 {
   1697 	/* Shortcut for GL functionality */
   1698 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1699 
   1700 	struct Shader
   1701 	{
   1702 		glw::GLchar const* const source;
   1703 		glw::GLenum const		 type;
   1704 		glw::GLuint				 id;
   1705 	} shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };
   1706 
   1707 	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
   1708 
   1709 	try
   1710 	{
   1711 		/* Create program. */
   1712 		m_po = gl.createProgram();
   1713 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
   1714 
   1715 		/* Shader compilation. */
   1716 
   1717 		for (glw::GLuint i = 0; i < shader_count; ++i)
   1718 		{
   1719 			if (DE_NULL != shader[i].source)
   1720 			{
   1721 				shader[i].id = gl.createShader(shader[i].type);
   1722 
   1723 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
   1724 
   1725 				gl.attachShader(m_po, shader[i].id);
   1726 
   1727 				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
   1728 
   1729 				gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
   1730 
   1731 				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
   1732 
   1733 				gl.compileShader(shader[i].id);
   1734 
   1735 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
   1736 
   1737 				glw::GLint status = GL_FALSE;
   1738 
   1739 				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
   1740 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
   1741 
   1742 				if (GL_FALSE == status)
   1743 				{
   1744 					glw::GLint log_size = 0;
   1745 					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
   1746 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
   1747 
   1748 					glw::GLchar* log_text = new glw::GLchar[log_size];
   1749 
   1750 					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
   1751 
   1752 					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
   1753 														<< "Shader type: " << glu::getShaderTypeStr(shader[i].type)
   1754 														<< "\n"
   1755 														<< "Shader compilation error log:\n"
   1756 														<< log_text << "\n"
   1757 														<< "Shader source code:\n"
   1758 														<< shader[i].source << "\n"
   1759 														<< tcu::TestLog::EndMessage;
   1760 
   1761 					delete[] log_text;
   1762 
   1763 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
   1764 
   1765 					throw 0;
   1766 				}
   1767 			}
   1768 		}
   1769 
   1770 		/* Transform Feedback setup. */
   1771 		gl.transformFeedbackVaryings(m_po, 1, &s_xfb_varying, GL_INTERLEAVED_ATTRIBS);
   1772 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
   1773 
   1774 		/* Link. */
   1775 		gl.linkProgram(m_po);
   1776 
   1777 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
   1778 
   1779 		glw::GLint status = GL_FALSE;
   1780 
   1781 		gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
   1782 
   1783 		if (GL_TRUE == status)
   1784 		{
   1785 			for (glw::GLuint i = 0; i < shader_count; ++i)
   1786 			{
   1787 				if (shader[i].id)
   1788 				{
   1789 					gl.detachShader(m_po, shader[i].id);
   1790 
   1791 					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
   1792 				}
   1793 			}
   1794 		}
   1795 		else
   1796 		{
   1797 			glw::GLint log_size = 0;
   1798 
   1799 			gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
   1800 
   1801 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
   1802 
   1803 			glw::GLchar* log_text = new glw::GLchar[log_size];
   1804 
   1805 			gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
   1806 
   1807 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
   1808 												<< log_text << "\n"
   1809 												<< tcu::TestLog::EndMessage;
   1810 
   1811 			delete[] log_text;
   1812 
   1813 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
   1814 
   1815 			throw 0;
   1816 		}
   1817 	}
   1818 	catch (...)
   1819 	{
   1820 		if (m_po)
   1821 		{
   1822 			gl.deleteProgram(m_po);
   1823 
   1824 			m_po = 0;
   1825 		}
   1826 	}
   1827 
   1828 	for (glw::GLuint i = 0; i < shader_count; ++i)
   1829 	{
   1830 		if (0 != shader[i].id)
   1831 		{
   1832 			gl.deleteShader(shader[i].id);
   1833 
   1834 			shader[i].id = 0;
   1835 		}
   1836 	}
   1837 
   1838 	if (m_po)
   1839 	{
   1840 		gl.useProgram(m_po);
   1841 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   1842 	}
   1843 
   1844 	if (0 == m_po)
   1845 	{
   1846 		throw 0;
   1847 	}
   1848 }
   1849 
   1850 /** @brief Create and bind empty vertex array object.
   1851  *
   1852  *  @note The function may throw if unexpected error has occured.
   1853  */
   1854 void FunctionalTest::prepareVertexArrayObject()
   1855 {
   1856 	/* Shortcut for GL functionality */
   1857 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1858 
   1859 	/* Creating and binding empty vertex array object. */
   1860 	gl.genVertexArrays(1, &m_vao);
   1861 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   1862 
   1863 	gl.bindVertexArray(m_vao);
   1864 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   1865 }
   1866 
   1867 /** @brief Draw with XFB.
   1868  *
   1869  *  @note Function follows steps:
   1870  *           Begin transform feedback environment.
   1871  *
   1872  *           Using the program with discarded rasterizer, draw array of 4 indices
   1873  *           using POINTS.
   1874  *
   1875  *           Pause transform feedback environment.
   1876  *
   1877  *           Query parameter TRANSFORM_FEEDBACK_PAUSED using GetTransformFeedbackiv.
   1878  *           Expect value equal to TRUE.
   1879  *
   1880  *           Query parameter TRANSFORM_FEEDBACK_ACTIVE using GetTransformFeedbackiv.
   1881  *           Expect value equal to TRUE.
   1882  *
   1883  *           Resume transform feedback environment.
   1884  *
   1885  *           Query parameter TRANSFORM_FEEDBACK_PAUSED using GetTransformFeedbackiv.
   1886  *           Expect value equal to FALSE.
   1887  *
   1888  *           Query parameter TRANSFORM_FEEDBACK_ACTIVE using GetTransformFeedbackiv.
   1889  *           Expect value equal to TRUE.
   1890  *
   1891  *           End Transform feedback environment.
   1892  *
   1893  *           Query parameter TRANSFORM_FEEDBACK_ACTIVE using GetTransformFeedbackiv.
   1894  *           Expect value equal to FALSE.
   1895  *
   1896  *  @note The function may throw if unexpected error has occured.
   1897  *
   1898  *  @return True if included tests succeded, false otherwise.
   1899  */
   1900 bool FunctionalTest::draw()
   1901 {
   1902 	/* Shortcut for GL functionality */
   1903 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1904 
   1905 	/* Default result. */
   1906 	bool is_ok = true;
   1907 
   1908 	/* Start transform feedback environment. */
   1909 	gl.bindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfb_dsa);
   1910 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTransformFeedback call failed.");
   1911 
   1912 	gl.beginTransformFeedback(GL_POINTS);
   1913 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   1914 
   1915 	/* Use only xfb. No rendering. */
   1916 	gl.enable(GL_RASTERIZER_DISCARD);
   1917 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnable(GL_RASTERIZER_DISCARD) call failed.");
   1918 
   1919 	/* Draw. */
   1920 	gl.drawArrays(GL_POINTS, 0, 4);
   1921 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   1922 
   1923 	/* Pause Transform Feedback and tests direct state queries related to paused state. */
   1924 	gl.pauseTransformFeedback();
   1925 	GLU_EXPECT_NO_ERROR(gl.getError(), "glPauseTransformFeedback call failed.");
   1926 
   1927 	is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_PAUSED, GL_TRUE);
   1928 	is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_ACTIVE, GL_TRUE);
   1929 
   1930 	/* Activate Transform Feedback and tests direct state queries related to paused state. */
   1931 	gl.resumeTransformFeedback();
   1932 	GLU_EXPECT_NO_ERROR(gl.getError(), "glPauseTransformFeedback call failed.");
   1933 
   1934 	is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_PAUSED, GL_FALSE);
   1935 	is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_ACTIVE, GL_TRUE);
   1936 
   1937 	/* Finish transform feedback. */
   1938 	gl.endTransformFeedback();
   1939 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   1940 
   1941 	is_ok &= testTransformFeedbackStatus(GL_TRANSFORM_FEEDBACK_ACTIVE, GL_FALSE);
   1942 
   1943 	return is_ok;
   1944 }
   1945 
   1946 /** @brief Check that selected Transform Feedback state has an expected value.
   1947  *
   1948  *  @param [in] parameter_name      Name of the parameter to be queried.
   1949  *                                  It must be GL_TRANSFORM_FEEDBACK_PAUSED or
   1950  *                                  GL_TRANSFORM_FEEDBACK_ACTIVE
   1951  *  @param [in] expected_value      The expected value of the query.
   1952  *
   1953  *  @note The function may throw if unexpected error has occured.
   1954  *
   1955  *  @return True if the queried value is equal to expected value, false otherwise.
   1956  */
   1957 bool FunctionalTest::testTransformFeedbackStatus(glw::GLenum parameter_name, glw::GLint expected_value)
   1958 {
   1959 	/* Shortcut for GL functionality */
   1960 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1961 
   1962 	/* Dummy storage. */
   1963 	glw::GLint value = 314159;
   1964 
   1965 	/* Test of GetTransformFeedbackiv. */
   1966 	m_gl_getTransformFeedbackiv(m_xfb_dsa, parameter_name, &value);
   1967 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTransformFeedbackiv call failed.");
   1968 
   1969 	if (expected_value != value)
   1970 	{
   1971 		m_context.getTestContext().getLog()
   1972 			<< tcu::TestLog::Message << "It was expected that glGetTransformFeedbackiv query of parameter "
   1973 			<< ((parameter_name == GL_TRANSFORM_FEEDBACK_PAUSED) ? "GL_TRANSFORM_FEEDBACK_PAUSED" :
   1974 																   "GL_TRANSFORM_FEEDBACK_ACTIVE")
   1975 			<< " shall return " << ((expected_value == GL_TRUE) ? "GL_TRUE" : "GL_FALSE") << "however, "
   1976 			<< ((value == GL_TRUE) ? "GL_TRUE" : "GL_FALSE") << " was returned." << tcu::TestLog::EndMessage;
   1977 
   1978 		return false;
   1979 	}
   1980 
   1981 	return true;
   1982 }
   1983 
   1984 /** @brief Check that transform feedback buffer contains
   1985  *         consecutive integer numbers from 0 to 3 (included).
   1986  *
   1987  *  @note The function may throw if unexpected error has occured.
   1988  *
   1989  *  @return True if buffer conatins consecutive integer
   1990  *          numbers from 0 to 3 (included), false otherwise.
   1991  */
   1992 bool FunctionalTest::verifyBufferContent()
   1993 {
   1994 	/* Shortcut for GL functionality */
   1995 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1996 
   1997 	/* Default result. */
   1998 	bool is_ok = true;
   1999 
   2000 	/* Mapping buffer object to the user-space. */
   2001 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo);
   2002 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   2003 
   2004 	glw::GLint* buffer = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   2005 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
   2006 
   2007 	for (glw::GLint i = 0; i < 4 /* Number of emitted vertices. */; ++i)
   2008 	{
   2009 		if (buffer[i] != i)
   2010 		{
   2011 			is_ok = false;
   2012 
   2013 			break;
   2014 		}
   2015 	}
   2016 
   2017 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   2018 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   2019 
   2020 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
   2021 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   2022 
   2023 	return is_ok;
   2024 }
   2025 
   2026 /** Release GL objects, return to the default state
   2027  */
   2028 void FunctionalTest::clean()
   2029 {
   2030 	/* Shortcut for GL functionality */
   2031 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2032 
   2033 	/* Release transform feedback object. */
   2034 	if (m_xfb_dsa)
   2035 	{
   2036 		gl.deleteTransformFeedbacks(1, &m_xfb_dsa);
   2037 
   2038 		m_xfb_dsa = 0;
   2039 	}
   2040 
   2041 	/* Release buffer object. */
   2042 	if (m_bo)
   2043 	{
   2044 		gl.deleteBuffers(1, &m_bo);
   2045 
   2046 		m_bo = 0;
   2047 	}
   2048 
   2049 	/* Release GLSL program. */
   2050 	if (m_po)
   2051 	{
   2052 		gl.useProgram(0);
   2053 
   2054 		gl.deleteProgram(m_po);
   2055 
   2056 		m_po = 0;
   2057 	}
   2058 
   2059 	/* Release vertex array object. */
   2060 	if (m_vao)
   2061 	{
   2062 		gl.bindVertexArray(0);
   2063 
   2064 		gl.deleteVertexArrays(1, &m_vao);
   2065 
   2066 		m_vao = 0;
   2067 	}
   2068 
   2069 	/* Returning to default rasterizer state. */
   2070 	gl.disable(GL_RASTERIZER_DISCARD);
   2071 }
   2072 
   2073 const glw::GLuint FunctionalTest::s_bo_size = 4 * sizeof(glw::GLint);
   2074 
   2075 const glw::GLchar FunctionalTest::s_vertex_shader[] = "#version 130\n"
   2076 													  "\n"
   2077 													  "out int result;\n"
   2078 													  "\n"
   2079 													  "void main()\n"
   2080 													  "{\n"
   2081 													  "\n"
   2082 													  "    result      = gl_VertexID;\n"
   2083 													  "    gl_Position = vec4(1.0);\n"
   2084 													  "}\n";
   2085 
   2086 const glw::GLchar FunctionalTest::s_fragment_shader[] = "#version 130\n"
   2087 														"\n"
   2088 														"out vec4 color;\n"
   2089 														"\n"
   2090 														"void main()\n"
   2091 														"{\n"
   2092 														"    color = vec4(0.0, 0.0, 0.0, 1.0);\n"
   2093 														"}\n";
   2094 
   2095 const glw::GLchar* const FunctionalTest::s_xfb_varying = "result";
   2096 
   2097 } /* TransformFeedback namespace */
   2098 } /* DirectStateAccess namespace */
   2099 } /* gl4cts namespace */
   2100