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