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  gl4cDirectStateAccessVertexArraysTests.cpp
     27  * \brief Conformance tests for the Direct State Access feature functionality (Vertex Array Objects 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 #include <algorithm>
     50 #include <climits>
     51 #include <cmath>
     52 #include <set>
     53 #include <sstream>
     54 #include <stack>
     55 
     56 namespace gl4cts
     57 {
     58 namespace DirectStateAccess
     59 {
     60 namespace VertexArrays
     61 {
     62 /******************************** Creation Test Implementation   ********************************/
     63 
     64 /** @brief Creation Test constructor.
     65  *
     66  *  @param [in] context     OpenGL context.
     67  */
     68 CreationTest::CreationTest(deqp::Context& context)
     69 	: deqp::TestCase(context, "vertex_arrays_creation", "Vertex Array Objects Creation Test")
     70 {
     71 	/* Intentionally left blank. */
     72 }
     73 
     74 /** @brief Iterate Creation Test cases.
     75  *
     76  *  @return Iteration result.
     77  */
     78 tcu::TestNode::IterateResult CreationTest::iterate()
     79 {
     80 	/* Shortcut for GL functionality. */
     81 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
     82 
     83 	/* Get context setup. */
     84 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
     85 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
     86 
     87 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
     88 	{
     89 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
     90 
     91 		return STOP;
     92 	}
     93 
     94 	/* Running tests. */
     95 	bool is_ok	= true;
     96 	bool is_error = false;
     97 
     98 	/* VertexArrays' objects */
     99 	static const glw::GLuint vertex_arrays_count = 2;
    100 
    101 	glw::GLuint vertex_arrays_legacy[vertex_arrays_count] = {};
    102 	glw::GLuint vertex_arrays_dsa[vertex_arrays_count]	= {};
    103 
    104 	try
    105 	{
    106 		/* Check legacy state creation. */
    107 		gl.genVertexArrays(vertex_arrays_count, vertex_arrays_legacy);
    108 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays have failed");
    109 
    110 		for (glw::GLuint i = 0; i < vertex_arrays_count; ++i)
    111 		{
    112 			if (gl.isVertexArray(vertex_arrays_legacy[i]))
    113 			{
    114 				is_ok = false;
    115 
    116 				/* Log. */
    117 				m_context.getTestContext().getLog()
    118 					<< tcu::TestLog::Message
    119 					<< "GenVertexArrays has created default objects, but it should create only a names."
    120 					<< tcu::TestLog::EndMessage;
    121 			}
    122 		}
    123 
    124 		/* Check direct state creation. */
    125 		gl.createVertexArrays(vertex_arrays_count, vertex_arrays_dsa);
    126 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays have failed");
    127 
    128 		for (glw::GLuint i = 0; i < vertex_arrays_count; ++i)
    129 		{
    130 			if (!gl.isVertexArray(vertex_arrays_dsa[i]))
    131 			{
    132 				is_ok = false;
    133 
    134 				/* Log. */
    135 				m_context.getTestContext().getLog() << tcu::TestLog::Message
    136 													<< "CreateVertexArrays has not created default objects."
    137 													<< tcu::TestLog::EndMessage;
    138 			}
    139 		}
    140 	}
    141 	catch (...)
    142 	{
    143 		is_ok	= false;
    144 		is_error = true;
    145 	}
    146 
    147 	/* Cleanup. */
    148 	for (glw::GLuint i = 0; i < vertex_arrays_count; ++i)
    149 	{
    150 		if (vertex_arrays_legacy[i])
    151 		{
    152 			gl.deleteVertexArrays(1, &vertex_arrays_legacy[i]);
    153 
    154 			vertex_arrays_legacy[i] = 0;
    155 		}
    156 
    157 		if (vertex_arrays_dsa[i])
    158 		{
    159 			gl.deleteVertexArrays(1, &vertex_arrays_dsa[i]);
    160 
    161 			vertex_arrays_dsa[i] = 0;
    162 		}
    163 	}
    164 
    165 	/* Errors clean up. */
    166 	while (gl.getError())
    167 		;
    168 
    169 	/* Result's setup. */
    170 	if (is_ok)
    171 	{
    172 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    173 	}
    174 	else
    175 	{
    176 		if (is_error)
    177 		{
    178 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
    179 		}
    180 		else
    181 		{
    182 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    183 		}
    184 	}
    185 
    186 	return STOP;
    187 }
    188 
    189 /******************************** Vertex Array Object Enable Disable Attributes Test Implementation   ********************************/
    190 
    191 /** @brief Vertex Array Object Enable Disable Attributes Test constructor.
    192  *
    193  *  @param [in] context     OpenGL context.
    194  */
    195 EnableDisableAttributesTest::EnableDisableAttributesTest(deqp::Context& context)
    196 	: deqp::TestCase(context, "vertex_arrays_enable_disable_attributes",
    197 					 "Vertex Array Objects Enable Disable Attributes Test")
    198 	, m_po_even(0)
    199 	, m_po_odd(0)
    200 	, m_vao(0)
    201 	, m_bo(0)
    202 	, m_bo_xfb(0)
    203 	, m_max_attributes(16) /* Required Minimum: OpenGL 4.5 Table 23.57: Implementation Dependent Vertex Shader Limits */
    204 {
    205 	/* Intentionally left blank. */
    206 }
    207 
    208 /** @brief Iterate Vertex Array Object Enable Disable Attributes Test cases.
    209  *
    210  *  @return Iteration result.
    211  */
    212 tcu::TestNode::IterateResult EnableDisableAttributesTest::iterate()
    213 {
    214 	/* Shortcut for GL functionality. */
    215 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    216 
    217 	/* Get context setup. */
    218 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    219 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
    220 
    221 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    222 	{
    223 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
    224 
    225 		return STOP;
    226 	}
    227 
    228 	/* Running tests. */
    229 	bool is_ok	= true;
    230 	bool is_error = false;
    231 
    232 	try
    233 	{
    234 		gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &m_max_attributes);
    235 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, ...) have failed");
    236 
    237 		m_po_even = PrepareProgram(false);
    238 		m_po_odd  = PrepareProgram(true);
    239 
    240 		PrepareVAO();
    241 		PrepareXFB();
    242 
    243 		is_ok &= TurnOnAttributes(true, false);
    244 		is_ok &= DrawAndCheck(false);
    245 
    246 		is_ok &= TurnOnAttributes(false, true);
    247 		is_ok &= DrawAndCheck(true);
    248 	}
    249 	catch (...)
    250 	{
    251 		is_ok	= false;
    252 		is_error = true;
    253 	}
    254 
    255 	/* Cleanup. */
    256 	Clean();
    257 
    258 	/* Errors clean up. */
    259 	while (gl.getError())
    260 		;
    261 
    262 	/* Result's setup. */
    263 	if (is_ok)
    264 	{
    265 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    266 	}
    267 	else
    268 	{
    269 		if (is_error)
    270 		{
    271 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
    272 		}
    273 		else
    274 		{
    275 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    276 		}
    277 	}
    278 
    279 	return STOP;
    280 }
    281 
    282 glw::GLuint EnableDisableAttributesTest::PrepareProgram(const bool bind_even_or_odd)
    283 {
    284 	/* Preprocess vertex shader sources. */
    285 	std::string declarations = "";
    286 	std::string copies		 = "    sum = 0;\n";
    287 
    288 	for (glw::GLint i = (glw::GLint)(bind_even_or_odd); i < m_max_attributes; i += 2)
    289 	{
    290 		declarations.append((std::string("in int a_").append(Utilities::itoa(i))).append(";\n"));
    291 		copies.append((std::string("    sum += a_").append(Utilities::itoa(i))).append(";\n"));
    292 	}
    293 
    294 	std::string vs_template(s_vertex_shader_template);
    295 
    296 	std::string vs_source = Utilities::replace(vs_template, "DECLARATION_TEMPLATE", declarations);
    297 	vs_source			  = Utilities::replace(vs_source, "COPY_TEMPLATE", copies);
    298 
    299 	/* Build and compile. */
    300 	return BuildProgram(vs_source.c_str(), bind_even_or_odd);
    301 }
    302 
    303 /** @brief Build test's GLSL program.
    304  *
    305  *  @note The function may throw if unexpected error has occured.
    306  */
    307 glw::GLuint EnableDisableAttributesTest::BuildProgram(const char* vertex_shader, const bool bind_even_or_odd)
    308 {
    309 	/* Shortcut for GL functionality */
    310 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    311 
    312 	struct Shader
    313 	{
    314 		glw::GLchar const* const source;
    315 		glw::GLenum const		 type;
    316 		glw::GLuint				 id;
    317 	} shader[] = { { vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };
    318 
    319 	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
    320 
    321 	glw::GLuint po = 0;
    322 
    323 	try
    324 	{
    325 		/* Create program. */
    326 		po = gl.createProgram();
    327 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
    328 
    329 		/* Shader compilation. */
    330 
    331 		for (glw::GLuint i = 0; i < shader_count; ++i)
    332 		{
    333 			if (DE_NULL != shader[i].source)
    334 			{
    335 				shader[i].id = gl.createShader(shader[i].type);
    336 
    337 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
    338 
    339 				gl.attachShader(po, shader[i].id);
    340 
    341 				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
    342 
    343 				gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
    344 
    345 				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
    346 
    347 				gl.compileShader(shader[i].id);
    348 
    349 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
    350 
    351 				glw::GLint status = GL_FALSE;
    352 
    353 				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
    354 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
    355 
    356 				if (GL_FALSE == status)
    357 				{
    358 					glw::GLint log_size = 0;
    359 					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
    360 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
    361 
    362 					glw::GLchar* log_text = new glw::GLchar[log_size];
    363 
    364 					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
    365 
    366 					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
    367 														<< "Shader type: " << glu::getShaderTypeStr(shader[i].type)
    368 														<< "\n"
    369 														<< "Shader compilation error log:\n"
    370 														<< log_text << "\n"
    371 														<< "Shader source code:\n"
    372 														<< shader[i].source << "\n"
    373 														<< tcu::TestLog::EndMessage;
    374 
    375 					delete[] log_text;
    376 
    377 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
    378 
    379 					throw 0;
    380 				}
    381 			}
    382 		}
    383 
    384 		/* Transform Feedback setup. */
    385 		static const glw::GLchar* xfb_varying = "sum";
    386 
    387 		gl.transformFeedbackVaryings(po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS);
    388 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
    389 
    390 		for (glw::GLint i = (glw::GLint)(bind_even_or_odd); i < m_max_attributes; i += 2)
    391 		{
    392 			std::string attribute = std::string("a_").append(Utilities::itoa(i));
    393 
    394 			gl.bindAttribLocation(po, i, attribute.c_str());
    395 			GLU_EXPECT_NO_ERROR(gl.getError(), "glBindAttribLocation call failed.");
    396 		}
    397 
    398 		/* Link. */
    399 		gl.linkProgram(po);
    400 
    401 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
    402 
    403 		glw::GLint status = GL_FALSE;
    404 
    405 		gl.getProgramiv(po, GL_LINK_STATUS, &status);
    406 
    407 		if (GL_TRUE == status)
    408 		{
    409 			for (glw::GLuint i = 0; i < shader_count; ++i)
    410 			{
    411 				if (shader[i].id)
    412 				{
    413 					gl.detachShader(po, shader[i].id);
    414 
    415 					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
    416 				}
    417 			}
    418 		}
    419 		else
    420 		{
    421 			glw::GLint log_size = 0;
    422 
    423 			gl.getProgramiv(po, GL_INFO_LOG_LENGTH, &log_size);
    424 
    425 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
    426 
    427 			glw::GLchar* log_text = new glw::GLchar[log_size];
    428 
    429 			gl.getProgramInfoLog(po, log_size, NULL, &log_text[0]);
    430 
    431 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
    432 												<< log_text << "\n"
    433 												<< tcu::TestLog::EndMessage;
    434 
    435 			delete[] log_text;
    436 
    437 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
    438 
    439 			throw 0;
    440 		}
    441 	}
    442 	catch (...)
    443 	{
    444 		if (po)
    445 		{
    446 			gl.deleteProgram(po);
    447 
    448 			po = 0;
    449 		}
    450 	}
    451 
    452 	for (glw::GLuint i = 0; i < shader_count; ++i)
    453 	{
    454 		if (0 != shader[i].id)
    455 		{
    456 			gl.deleteShader(shader[i].id);
    457 
    458 			shader[i].id = 0;
    459 		}
    460 	}
    461 
    462 	if (0 == po)
    463 	{
    464 		throw 0;
    465 	}
    466 
    467 	return po;
    468 }
    469 
    470 /** @brief Prepare vertex array object for the test.
    471  */
    472 void EnableDisableAttributesTest::PrepareVAO()
    473 {
    474 	/* Shortcut for GL functionality */
    475 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    476 
    477 	/* VAO creation. */
    478 	gl.genVertexArrays(1, &m_vao);
    479 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
    480 
    481 	gl.bindVertexArray(m_vao);
    482 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
    483 
    484 	/* Buffer creation. */
    485 	gl.genBuffers(1, &m_bo);
    486 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
    487 
    488 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo);
    489 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
    490 
    491 	glw::GLint* reference_data = new glw::GLint[m_max_attributes];
    492 
    493 	if (DE_NULL == reference_data)
    494 	{
    495 		throw 0;
    496 	}
    497 
    498 	for (glw::GLint i = 0; i < m_max_attributes; ++i)
    499 	{
    500 		reference_data[i] = i;
    501 	}
    502 
    503 	gl.bufferData(GL_ARRAY_BUFFER, sizeof(glw::GLint) * m_max_attributes, reference_data, GL_STATIC_DRAW);
    504 
    505 	delete[] reference_data;
    506 
    507 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
    508 
    509 	/* VAO setup. */
    510 	for (glw::GLint i = 0; i < m_max_attributes; ++i)
    511 	{
    512 		gl.vertexAttribIPointer(i, 1, GL_INT, static_cast<glw::GLsizei>(sizeof(glw::GLint) * m_max_attributes),
    513 								(glw::GLvoid*)((glw::GLint*)NULL + i));
    514 
    515 		GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer call failed.");
    516 	}
    517 }
    518 
    519 /** @brief Prepare buffer object for test GLSL program transform feedback results.
    520  */
    521 void EnableDisableAttributesTest::PrepareXFB()
    522 {
    523 	/* Shortcut for GL functionality */
    524 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    525 
    526 	/* Buffer creation. */
    527 	gl.genBuffers(1, &m_bo_xfb);
    528 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
    529 
    530 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
    531 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
    532 
    533 	/* Preparing storage. */
    534 	gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(glw::GLint), NULL, GL_MAP_READ_BIT);
    535 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed.");
    536 
    537 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
    538 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
    539 }
    540 
    541 /** @brief Draw test program, fetch transform feedback results and compare them with expected values.
    542  *
    543  *  @param [in] bind_even_or_odd         Even or odd attribute are enabled.
    544  *
    545  *  @return True if expected results are equal to returned by XFB, false otherwise.
    546  */
    547 bool EnableDisableAttributesTest::DrawAndCheck(bool bind_even_or_odd)
    548 {
    549 	/* Shortcut for GL functionality */
    550 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    551 
    552 	/* Setup state. */
    553 	gl.useProgram(bind_even_or_odd ? m_po_odd : m_po_even);
    554 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
    555 
    556 	gl.bindVertexArray(m_vao);
    557 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
    558 
    559 	gl.beginTransformFeedback(GL_POINTS);
    560 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
    561 
    562 	/* Draw. */
    563 	gl.drawArrays(GL_POINTS, 0, 1);
    564 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
    565 
    566 	/* State reset. */
    567 	gl.endTransformFeedback();
    568 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
    569 
    570 	/* Result query. */
    571 	glw::GLint* result_ptr = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
    572 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
    573 
    574 	glw::GLint result = *result_ptr;
    575 
    576 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
    577 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
    578 
    579 	/* Check result and return. */
    580 	if (bind_even_or_odd)
    581 	{
    582 		glw::GLint reference_sum = 0;
    583 
    584 		for (glw::GLint i = 1; i < m_max_attributes; i += 2)
    585 		{
    586 			reference_sum += i;
    587 		}
    588 
    589 		if (reference_sum == result)
    590 		{
    591 			return true;
    592 		}
    593 	}
    594 	else
    595 	{
    596 		glw::GLint reference_sum = 0;
    597 
    598 		for (glw::GLint i = 0; i < m_max_attributes; i += 2)
    599 		{
    600 			reference_sum += i;
    601 		}
    602 
    603 		if (reference_sum == result)
    604 		{
    605 			return true;
    606 		}
    607 	}
    608 
    609 	return false;
    610 }
    611 
    612 /** @brief Turn on even or odd attributes (up to m_max_attributes) using EnableVertexArrayAttrib function.
    613  *
    614  *  @param [in] enable_even         Turn on even attribute indexes.
    615  *  @param [in] enable_odd          Turn on odd  attribute indexes.
    616  *
    617  *  @return True if EnableVertexArrayAttrib does not generate any error, false otherwise.
    618  */
    619 bool EnableDisableAttributesTest::TurnOnAttributes(bool enable_even, bool enable_odd)
    620 {
    621 	/* Shortcut for GL functionality */
    622 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    623 
    624 	gl.bindVertexArray(0);
    625 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
    626 
    627 	for (glw::GLint i = 0; i < m_max_attributes; ++i)
    628 	{
    629 		bool disable = true;
    630 
    631 		if (i % 2) /* if odd */
    632 		{
    633 			if (enable_odd)
    634 			{
    635 				gl.enableVertexArrayAttrib(m_vao, i);
    636 
    637 				if (glw::GLenum error = gl.getError())
    638 				{
    639 					m_context.getTestContext().getLog()
    640 						<< tcu::TestLog::Message << "glEnableVertexArrayAttrib generated error "
    641 						<< glu::getErrorStr(error) << " when called with VAO " << m_vao << " and index " << i << "."
    642 						<< tcu::TestLog::EndMessage;
    643 
    644 					return false;
    645 				}
    646 
    647 				disable = false;
    648 			}
    649 		}
    650 		else
    651 		{
    652 			if (enable_even)
    653 			{
    654 				gl.enableVertexArrayAttrib(m_vao, i);
    655 
    656 				if (glw::GLenum error = gl.getError())
    657 				{
    658 					m_context.getTestContext().getLog()
    659 						<< tcu::TestLog::Message << "glEnableVertexArrayAttrib generated error "
    660 						<< glu::getErrorStr(error) << " when called with VAO " << m_vao << " and index " << i << "."
    661 						<< tcu::TestLog::EndMessage;
    662 
    663 					return false;
    664 				}
    665 
    666 				disable = false;
    667 			}
    668 		}
    669 
    670 		if (disable)
    671 		{
    672 			gl.disableVertexArrayAttrib(m_vao, i);
    673 
    674 			if (glw::GLenum error = gl.getError())
    675 			{
    676 				m_context.getTestContext().getLog()
    677 					<< tcu::TestLog::Message << "glDisableVertexArrayAttrib generated error " << glu::getErrorStr(error)
    678 					<< " when called with VAO " << m_vao << " and index " << i << "." << tcu::TestLog::EndMessage;
    679 
    680 				return false;
    681 			}
    682 		}
    683 	}
    684 
    685 	gl.bindVertexArray(m_vao);
    686 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
    687 
    688 	return true;
    689 }
    690 
    691 /** @brief Clean GL objects. */
    692 void EnableDisableAttributesTest::Clean()
    693 {
    694 	/* Shortcut for GL functionality */
    695 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    696 
    697 	gl.useProgram(0);
    698 
    699 	if (m_po_even)
    700 	{
    701 		gl.deleteProgram(m_po_even);
    702 
    703 		m_po_even = 0;
    704 	}
    705 
    706 	if (m_po_odd)
    707 	{
    708 		gl.deleteProgram(m_po_odd);
    709 
    710 		m_po_odd = 0;
    711 	}
    712 
    713 	if (m_vao)
    714 	{
    715 		gl.deleteVertexArrays(1, &m_vao);
    716 
    717 		m_vao = 0;
    718 	}
    719 
    720 	if (m_bo)
    721 	{
    722 		gl.deleteBuffers(1, &m_bo);
    723 
    724 		m_bo = 0;
    725 	}
    726 
    727 	if (m_bo_xfb)
    728 	{
    729 		gl.deleteBuffers(1, &m_bo_xfb);
    730 
    731 		m_bo_xfb = 0;
    732 	}
    733 
    734 	if (m_max_attributes)
    735 	{
    736 		m_max_attributes =
    737 			16; /* OpenGL 4.5 Required Minimum Table 23.57: Implementation Dependent Vertex Shader Limits */
    738 	}
    739 
    740 	while (gl.getError())
    741 		;
    742 }
    743 
    744 std::string Utilities::itoa(glw::GLuint i)
    745 {
    746 	std::string s = "";
    747 
    748 	std::stringstream ss;
    749 
    750 	ss << i;
    751 
    752 	s = ss.str();
    753 
    754 	return s;
    755 }
    756 
    757 std::string Utilities::replace(const std::string& src, const std::string& key, const std::string& value)
    758 {
    759 	size_t		pos = 0;
    760 	std::string dst = src;
    761 
    762 	while (std::string::npos != (pos = dst.find(key, pos)))
    763 	{
    764 		dst.replace(pos, key.length(), value);
    765 		pos += key.length();
    766 	}
    767 
    768 	return dst;
    769 }
    770 
    771 const glw::GLchar EnableDisableAttributesTest::s_vertex_shader_template[] = "#version 450\n"
    772 																			"\n"
    773 																			"DECLARATION_TEMPLATE"
    774 																			"out int sum;\n"
    775 																			"\n"
    776 																			"void main()\n"
    777 																			"{\n"
    778 																			"COPY_TEMPLATE"
    779 																			"}\n";
    780 
    781 const glw::GLchar EnableDisableAttributesTest::s_fragment_shader[] = "#version 450\n"
    782 																	 "\n"
    783 																	 "out vec4 color;\n"
    784 																	 "\n"
    785 																	 "void main()\n"
    786 																	 "{\n"
    787 																	 "    color = vec4(1.0);"
    788 																	 "}\n";
    789 
    790 /******************************** Vertex Array Object Element Buffer Test Implementation   ********************************/
    791 
    792 /** @brief Vertex Array Object Element Buffer Test constructor.
    793  *
    794  *  @param [in] context     OpenGL context.
    795  */
    796 ElementBufferTest::ElementBufferTest(deqp::Context& context)
    797 	: deqp::TestCase(context, "vertex_arrays_element_buffer", "Vertex Array Objects Element Buffer Test")
    798 	, m_po(0)
    799 	, m_vao(0)
    800 	, m_bo_array(0)
    801 	, m_bo_elements(0)
    802 	, m_bo_xfb(0)
    803 {
    804 	/* Intentionally left blank. */
    805 }
    806 
    807 /** @brief Iterate Vertex Array Object Enable Disable Attributes Test cases.
    808  *
    809  *  @return Iteration result.
    810  */
    811 tcu::TestNode::IterateResult ElementBufferTest::iterate()
    812 {
    813 	/* Shortcut for GL functionality. */
    814 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    815 
    816 	/* Get context setup. */
    817 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
    818 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
    819 
    820 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
    821 	{
    822 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
    823 
    824 		return STOP;
    825 	}
    826 
    827 	/* Running tests. */
    828 	bool is_ok	= true;
    829 	bool is_error = false;
    830 
    831 	try
    832 	{
    833 		PrepareProgram();
    834 		is_ok &= PrepareVAO();
    835 		PrepareXFB();
    836 		is_ok &= DrawAndCheck();
    837 	}
    838 	catch (...)
    839 	{
    840 		is_ok	= false;
    841 		is_error = true;
    842 	}
    843 
    844 	/* Cleanup. */
    845 	Clean();
    846 
    847 	/* Errors clean up. */
    848 	while (gl.getError())
    849 		;
    850 
    851 	/* Result's setup. */
    852 	if (is_ok)
    853 	{
    854 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    855 	}
    856 	else
    857 	{
    858 		if (is_error)
    859 		{
    860 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
    861 		}
    862 		else
    863 		{
    864 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    865 		}
    866 	}
    867 
    868 	return STOP;
    869 }
    870 
    871 /** @brief Build test's GLSL program.
    872  *
    873  *  @note The function may throw if unexpected error has occured.
    874  */
    875 void ElementBufferTest::PrepareProgram()
    876 {
    877 	/* Shortcut for GL functionality */
    878 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
    879 
    880 	struct Shader
    881 	{
    882 		glw::GLchar const* const source;
    883 		glw::GLenum const		 type;
    884 		glw::GLuint				 id;
    885 	} shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };
    886 
    887 	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
    888 
    889 	try
    890 	{
    891 		/* Create program. */
    892 		m_po = gl.createProgram();
    893 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
    894 
    895 		/* Shader compilation. */
    896 
    897 		for (glw::GLuint i = 0; i < shader_count; ++i)
    898 		{
    899 			if (DE_NULL != shader[i].source)
    900 			{
    901 				shader[i].id = gl.createShader(shader[i].type);
    902 
    903 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
    904 
    905 				gl.attachShader(m_po, shader[i].id);
    906 
    907 				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
    908 
    909 				gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
    910 
    911 				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
    912 
    913 				gl.compileShader(shader[i].id);
    914 
    915 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
    916 
    917 				glw::GLint status = GL_FALSE;
    918 
    919 				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
    920 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
    921 
    922 				if (GL_FALSE == status)
    923 				{
    924 					glw::GLint log_size = 0;
    925 					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
    926 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
    927 
    928 					glw::GLchar* log_text = new glw::GLchar[log_size];
    929 
    930 					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
    931 
    932 					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
    933 														<< "Shader type: " << glu::getShaderTypeStr(shader[i].type)
    934 														<< "\n"
    935 														<< "Shader compilation error log:\n"
    936 														<< log_text << "\n"
    937 														<< "Shader source code:\n"
    938 														<< shader[i].source << "\n"
    939 														<< tcu::TestLog::EndMessage;
    940 
    941 					delete[] log_text;
    942 
    943 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
    944 
    945 					throw 0;
    946 				}
    947 			}
    948 		}
    949 
    950 		/* Transform Feedback setup. */
    951 		static const glw::GLchar* xfb_varying = "result";
    952 
    953 		gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS);
    954 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
    955 
    956 		/* Link. */
    957 		gl.linkProgram(m_po);
    958 
    959 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
    960 
    961 		glw::GLint status = GL_FALSE;
    962 
    963 		gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
    964 
    965 		if (GL_TRUE == status)
    966 		{
    967 			for (glw::GLuint i = 0; i < shader_count; ++i)
    968 			{
    969 				if (shader[i].id)
    970 				{
    971 					gl.detachShader(m_po, shader[i].id);
    972 
    973 					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
    974 				}
    975 			}
    976 		}
    977 		else
    978 		{
    979 			glw::GLint log_size = 0;
    980 
    981 			gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
    982 
    983 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
    984 
    985 			glw::GLchar* log_text = new glw::GLchar[log_size];
    986 
    987 			gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
    988 
    989 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
    990 												<< log_text << "\n"
    991 												<< tcu::TestLog::EndMessage;
    992 
    993 			delete[] log_text;
    994 
    995 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
    996 
    997 			throw 0;
    998 		}
    999 	}
   1000 	catch (...)
   1001 	{
   1002 		if (m_po)
   1003 		{
   1004 			gl.deleteProgram(m_po);
   1005 
   1006 			m_po = 0;
   1007 		}
   1008 	}
   1009 
   1010 	for (glw::GLuint i = 0; i < shader_count; ++i)
   1011 	{
   1012 		if (0 != shader[i].id)
   1013 		{
   1014 			gl.deleteShader(shader[i].id);
   1015 
   1016 			shader[i].id = 0;
   1017 		}
   1018 	}
   1019 
   1020 	if (0 == m_po)
   1021 	{
   1022 		throw 0;
   1023 	}
   1024 }
   1025 
   1026 /** @brief Prepare vertex array object for the test of VertexArrayElementBuffer function.
   1027  *
   1028  *  @return True if function VertexArrayElementBuffer* does not generate any error.
   1029  */
   1030 bool ElementBufferTest::PrepareVAO()
   1031 {
   1032 	/* Shortcut for GL functionality */
   1033 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1034 
   1035 	/* VAO creation. */
   1036 	gl.genVertexArrays(1, &m_vao);
   1037 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   1038 
   1039 	gl.bindVertexArray(m_vao);
   1040 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   1041 
   1042 	/* Array buffer creation. */
   1043 	glw::GLint array_data[3] = { 2, 1, 0 };
   1044 
   1045 	gl.genBuffers(1, &m_bo_array);
   1046 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   1047 
   1048 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array);
   1049 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   1050 
   1051 	gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data), array_data, GL_STATIC_DRAW);
   1052 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   1053 
   1054 	gl.vertexAttribIPointer(gl.getAttribLocation(m_po, "a"), 1, GL_INT, 0, NULL);
   1055 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer call failed.");
   1056 
   1057 	gl.enableVertexAttribArray(0);
   1058 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   1059 
   1060 	gl.bindVertexArray(0);
   1061 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   1062 
   1063 	/* Element buffer creation. */
   1064 	glw::GLuint elements_data[3] = { 2, 1, 0 };
   1065 
   1066 	gl.genBuffers(1, &m_bo_elements);
   1067 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   1068 
   1069 	gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_bo_elements);
   1070 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   1071 
   1072 	gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements_data), elements_data, GL_STATIC_DRAW);
   1073 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   1074 
   1075 	gl.vertexArrayElementBuffer(m_vao, m_bo_elements);
   1076 
   1077 	if (glw::GLenum error = gl.getError())
   1078 	{
   1079 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   1080 											<< "VertexArrayElementBuffer has unexpectedly generated "
   1081 											<< glu::getErrorStr(error) << "error. Test fails.\n"
   1082 											<< tcu::TestLog::EndMessage;
   1083 
   1084 		return false;
   1085 	}
   1086 
   1087 	return true;
   1088 }
   1089 
   1090 /** @brief Prepare buffer object for test GLSL program transform feedback results.
   1091  */
   1092 void ElementBufferTest::PrepareXFB()
   1093 {
   1094 	/* Shortcut for GL functionality */
   1095 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1096 
   1097 	/* Buffer creation. */
   1098 	gl.genBuffers(1, &m_bo_xfb);
   1099 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   1100 
   1101 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
   1102 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   1103 
   1104 	/* Preparing storage. */
   1105 	gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, 3 * sizeof(glw::GLint), NULL, GL_MAP_READ_BIT);
   1106 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed.");
   1107 
   1108 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
   1109 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
   1110 }
   1111 
   1112 /** @brief Draw test program, fetch transform feedback results and compare them with expected values.
   1113  *
   1114  *  @return True if expected results are equal to returned by XFB, false otherwise.
   1115  */
   1116 bool ElementBufferTest::DrawAndCheck()
   1117 {
   1118 	/* Shortcut for GL functionality */
   1119 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1120 
   1121 	/* Setup state. */
   1122 	gl.useProgram(m_po);
   1123 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   1124 
   1125 	gl.bindVertexArray(m_vao);
   1126 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   1127 
   1128 	gl.beginTransformFeedback(GL_POINTS);
   1129 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   1130 
   1131 	/* Draw. */
   1132 	gl.drawElements(GL_POINTS, 3, GL_UNSIGNED_INT, NULL);
   1133 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   1134 
   1135 	/* State reset. */
   1136 	gl.endTransformFeedback();
   1137 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   1138 
   1139 	/* Result query. */
   1140 	glw::GLint* result_ptr = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   1141 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
   1142 
   1143 	glw::GLint result[3] = { result_ptr[0], result_ptr[1], result_ptr[2] };
   1144 
   1145 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   1146 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   1147 
   1148 	/* Check result and return. */
   1149 	for (glw::GLint i = 0; i < 3; ++i)
   1150 	{
   1151 		if (i != result[i])
   1152 		{
   1153 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Result vector is equal to [" << result[0]
   1154 												<< ", " << result[1] << ", " << result[2]
   1155 												<< "], but [0, 1, 2] was expected." << tcu::TestLog::EndMessage;
   1156 
   1157 			return false;
   1158 		}
   1159 	}
   1160 
   1161 	return true;
   1162 }
   1163 
   1164 /** @brief Clean GL objects. */
   1165 void ElementBufferTest::Clean()
   1166 {
   1167 	/* Shortcut for GL functionality */
   1168 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1169 
   1170 	gl.useProgram(0);
   1171 
   1172 	if (m_po)
   1173 	{
   1174 		gl.deleteProgram(m_po);
   1175 
   1176 		m_po = 0;
   1177 	}
   1178 
   1179 	if (m_vao)
   1180 	{
   1181 		gl.deleteVertexArrays(1, &m_vao);
   1182 
   1183 		m_vao = 0;
   1184 	}
   1185 
   1186 	if (m_bo_array)
   1187 	{
   1188 		gl.deleteBuffers(1, &m_bo_array);
   1189 
   1190 		m_bo_array = 0;
   1191 	}
   1192 
   1193 	if (m_bo_elements)
   1194 	{
   1195 		gl.deleteBuffers(1, &m_bo_elements);
   1196 
   1197 		m_bo_elements = 0;
   1198 	}
   1199 
   1200 	if (m_bo_xfb)
   1201 	{
   1202 		gl.deleteBuffers(1, &m_bo_xfb);
   1203 
   1204 		m_bo_xfb = 0;
   1205 	}
   1206 
   1207 	while (gl.getError())
   1208 		;
   1209 }
   1210 
   1211 const glw::GLchar ElementBufferTest::s_vertex_shader[] = "#version 450\n"
   1212 														 "\n"
   1213 														 "in int a;"
   1214 														 "out int result;\n"
   1215 														 "\n"
   1216 														 "void main()\n"
   1217 														 "{\n"
   1218 														 "    gl_Position = vec4(1.0);\n"
   1219 														 "    result = a;"
   1220 														 "}\n";
   1221 
   1222 const glw::GLchar ElementBufferTest::s_fragment_shader[] = "#version 450\n"
   1223 														   "\n"
   1224 														   "out vec4 color;\n"
   1225 														   "\n"
   1226 														   "void main()\n"
   1227 														   "{\n"
   1228 														   "    color = vec4(1.0);"
   1229 														   "}\n";
   1230 
   1231 /******************************** Vertex Array Object Vertex Buffer and Buffers Test Implementation   ********************************/
   1232 
   1233 /** @brief Vertex Array Object Element Buffer Test constructor.
   1234  *
   1235  *  @param [in] context     OpenGL context.
   1236  */
   1237 VertexBuffersTest::VertexBuffersTest(deqp::Context& context)
   1238 	: deqp::TestCase(context, "vertex_arrays_vertex_buffers", "Vertex Array Object Vertex Buffer and Buffers Test")
   1239 	, m_po(0)
   1240 	, m_vao(0)
   1241 	, m_bo_array_0(0)
   1242 	, m_bo_array_1(0)
   1243 	, m_bo_xfb(0)
   1244 {
   1245 	/* Intentionally left blank. */
   1246 }
   1247 
   1248 /** @brief Iterate Vertex Array Object Enable Disable Attributes Test cases.
   1249  *
   1250  *  @return Iteration result.
   1251  */
   1252 tcu::TestNode::IterateResult VertexBuffersTest::iterate()
   1253 {
   1254 	/* Shortcut for GL functionality. */
   1255 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1256 
   1257 	/* Get context setup. */
   1258 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
   1259 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
   1260 
   1261 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
   1262 	{
   1263 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
   1264 
   1265 		return STOP;
   1266 	}
   1267 
   1268 	/* Running tests. */
   1269 	bool is_ok	= true;
   1270 	bool is_error = false;
   1271 
   1272 	try
   1273 	{
   1274 		PrepareProgram();
   1275 		is_ok &= PrepareVAO(false);
   1276 		PrepareXFB();
   1277 		is_ok &= DrawAndCheck();
   1278 		Clean();
   1279 
   1280 		PrepareProgram();
   1281 		is_ok &= PrepareVAO(true);
   1282 		PrepareXFB();
   1283 		is_ok &= DrawAndCheck();
   1284 	}
   1285 	catch (...)
   1286 	{
   1287 		is_ok	= false;
   1288 		is_error = true;
   1289 	}
   1290 
   1291 	/* Cleanup. */
   1292 	Clean();
   1293 
   1294 	/* Errors clean up. */
   1295 	while (gl.getError())
   1296 		;
   1297 
   1298 	/* Result's setup. */
   1299 	if (is_ok)
   1300 	{
   1301 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1302 	}
   1303 	else
   1304 	{
   1305 		if (is_error)
   1306 		{
   1307 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   1308 		}
   1309 		else
   1310 		{
   1311 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1312 		}
   1313 	}
   1314 
   1315 	return STOP;
   1316 }
   1317 
   1318 /** @brief Build test's GLSL program.
   1319  *
   1320  *  @note The function may throw if unexpected error has occured.
   1321  */
   1322 void VertexBuffersTest::PrepareProgram()
   1323 {
   1324 	/* Shortcut for GL functionality */
   1325 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1326 
   1327 	struct Shader
   1328 	{
   1329 		glw::GLchar const* const source;
   1330 		glw::GLenum const		 type;
   1331 		glw::GLuint				 id;
   1332 	} shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };
   1333 
   1334 	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
   1335 
   1336 	try
   1337 	{
   1338 		/* Create program. */
   1339 		m_po = gl.createProgram();
   1340 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
   1341 
   1342 		/* Shader compilation. */
   1343 
   1344 		for (glw::GLuint i = 0; i < shader_count; ++i)
   1345 		{
   1346 			if (DE_NULL != shader[i].source)
   1347 			{
   1348 				shader[i].id = gl.createShader(shader[i].type);
   1349 
   1350 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
   1351 
   1352 				gl.attachShader(m_po, shader[i].id);
   1353 
   1354 				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
   1355 
   1356 				gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
   1357 
   1358 				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
   1359 
   1360 				gl.compileShader(shader[i].id);
   1361 
   1362 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
   1363 
   1364 				glw::GLint status = GL_FALSE;
   1365 
   1366 				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
   1367 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
   1368 
   1369 				if (GL_FALSE == status)
   1370 				{
   1371 					glw::GLint log_size = 0;
   1372 					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
   1373 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
   1374 
   1375 					glw::GLchar* log_text = new glw::GLchar[log_size];
   1376 
   1377 					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
   1378 
   1379 					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
   1380 														<< "Shader type: " << glu::getShaderTypeStr(shader[i].type)
   1381 														<< "\n"
   1382 														<< "Shader compilation error log:\n"
   1383 														<< log_text << "\n"
   1384 														<< "Shader source code:\n"
   1385 														<< shader[i].source << "\n"
   1386 														<< tcu::TestLog::EndMessage;
   1387 
   1388 					delete[] log_text;
   1389 
   1390 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
   1391 
   1392 					throw 0;
   1393 				}
   1394 			}
   1395 		}
   1396 
   1397 		/* Transform Feedback setup. */
   1398 		static const glw::GLchar* xfb_varying = "result";
   1399 
   1400 		gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS);
   1401 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
   1402 
   1403 		/* Link. */
   1404 		gl.linkProgram(m_po);
   1405 
   1406 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
   1407 
   1408 		glw::GLint status = GL_FALSE;
   1409 
   1410 		gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
   1411 
   1412 		if (GL_TRUE == status)
   1413 		{
   1414 			for (glw::GLuint i = 0; i < shader_count; ++i)
   1415 			{
   1416 				if (shader[i].id)
   1417 				{
   1418 					gl.detachShader(m_po, shader[i].id);
   1419 
   1420 					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
   1421 				}
   1422 			}
   1423 		}
   1424 		else
   1425 		{
   1426 			glw::GLint log_size = 0;
   1427 
   1428 			gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
   1429 
   1430 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
   1431 
   1432 			glw::GLchar* log_text = new glw::GLchar[log_size];
   1433 
   1434 			gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
   1435 
   1436 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
   1437 												<< log_text << "\n"
   1438 												<< tcu::TestLog::EndMessage;
   1439 
   1440 			delete[] log_text;
   1441 
   1442 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
   1443 
   1444 			throw 0;
   1445 		}
   1446 	}
   1447 	catch (...)
   1448 	{
   1449 		if (m_po)
   1450 		{
   1451 			gl.deleteProgram(m_po);
   1452 
   1453 			m_po = 0;
   1454 		}
   1455 	}
   1456 
   1457 	for (glw::GLuint i = 0; i < shader_count; ++i)
   1458 	{
   1459 		if (0 != shader[i].id)
   1460 		{
   1461 			gl.deleteShader(shader[i].id);
   1462 
   1463 			shader[i].id = 0;
   1464 		}
   1465 	}
   1466 
   1467 	if (0 == m_po)
   1468 	{
   1469 		throw 0;
   1470 	}
   1471 }
   1472 
   1473 /** @brief Prepare vertex array object for the test of gl.vertexArrayVertexBuffer* functions.
   1474  *
   1475  *  @param [in] use_multiple_buffers_function    Use gl.vertexArrayVertexBuffers instead of gl.vertexArrayVertexBuffer.
   1476  *
   1477  *  @return True if functions gl.vertexArrayVertexBuffer* do not generate any error.
   1478  */
   1479 bool VertexBuffersTest::PrepareVAO(bool use_multiple_buffers_function)
   1480 {
   1481 	/* Shortcut for GL functionality */
   1482 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1483 
   1484 	/* VAO creation. */
   1485 	gl.genVertexArrays(1, &m_vao);
   1486 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   1487 
   1488 	gl.bindVertexArray(m_vao);
   1489 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   1490 
   1491 	/* Array buffer 0 creation. */
   1492 	glw::GLint array_data_0[4] = { 0, 2, 1, 3 };
   1493 
   1494 	gl.genBuffers(1, &m_bo_array_0);
   1495 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   1496 
   1497 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array_0);
   1498 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   1499 
   1500 	gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data_0), array_data_0, GL_STATIC_DRAW);
   1501 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   1502 
   1503 	gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_0"), 0);
   1504 
   1505 	gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_1"), 1);
   1506 
   1507 	gl.vertexAttribIFormat(gl.getAttribLocation(m_po, "a_0"), 1, GL_INT, 0);
   1508 
   1509 	gl.vertexAttribIFormat(gl.getAttribLocation(m_po, "a_1"), 1, GL_INT, 0);
   1510 
   1511 	if (use_multiple_buffers_function)
   1512 	{
   1513 		const glw::GLuint		   buffers[2] = { m_bo_array_0, m_bo_array_0 };
   1514 		static const glw::GLintptr offsets[2] = { (glw::GLintptr)NULL, (glw::GLintptr)((glw::GLint*)NULL + 1) };
   1515 		static const glw::GLsizei  strides[2] = { sizeof(glw::GLint) * 2, sizeof(glw::GLint) * 2 };
   1516 
   1517 		gl.vertexArrayVertexBuffers(m_vao, 0, 2, buffers, offsets, strides);
   1518 
   1519 		if (glw::GLenum error = gl.getError())
   1520 		{
   1521 			m_context.getTestContext().getLog() << tcu::TestLog::Message
   1522 												<< "VertexArrayVertexBuffers has unexpectedly generated "
   1523 												<< glu::getErrorStr(error) << "error. Test fails.\n"
   1524 												<< tcu::TestLog::EndMessage;
   1525 
   1526 			return false;
   1527 		}
   1528 	}
   1529 	else
   1530 	{
   1531 		gl.vertexArrayVertexBuffer(m_vao, 0, m_bo_array_0, (glw::GLintptr)NULL, sizeof(glw::GLint) * 2);
   1532 
   1533 		if (glw::GLenum error = gl.getError())
   1534 		{
   1535 			m_context.getTestContext().getLog() << tcu::TestLog::Message
   1536 												<< "VertexArrayVertexBuffer has unexpectedly generated "
   1537 												<< glu::getErrorStr(error) << "error. Test fails.\n"
   1538 												<< tcu::TestLog::EndMessage;
   1539 
   1540 			return false;
   1541 		}
   1542 
   1543 		gl.vertexArrayVertexBuffer(m_vao, 1, m_bo_array_0, (glw::GLintptr)((glw::GLint*)NULL + 1),
   1544 								   sizeof(glw::GLint) * 2);
   1545 
   1546 		if (glw::GLenum error = gl.getError())
   1547 		{
   1548 			m_context.getTestContext().getLog() << tcu::TestLog::Message
   1549 												<< "VertexArrayVertexBuffer has unexpectedly generated "
   1550 												<< glu::getErrorStr(error) << "error. Test fails.\n"
   1551 												<< tcu::TestLog::EndMessage;
   1552 
   1553 			return false;
   1554 		}
   1555 	}
   1556 
   1557 	gl.enableVertexAttribArray(0);
   1558 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   1559 
   1560 	gl.enableVertexAttribArray(1);
   1561 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   1562 
   1563 	/* Array buffer 1 creation. */
   1564 	glw::GLint array_data_1[2] = { 4, 5 };
   1565 
   1566 	gl.genBuffers(1, &m_bo_array_1);
   1567 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   1568 
   1569 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array_1);
   1570 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   1571 
   1572 	gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data_1), array_data_1, GL_STATIC_DRAW);
   1573 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   1574 
   1575 	gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_2"), 2);
   1576 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed.");
   1577 
   1578 	gl.vertexAttribIFormat(gl.getAttribLocation(m_po, "a_2"), 1, GL_INT, 0);
   1579 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIFormat call failed.");
   1580 
   1581 	if (use_multiple_buffers_function)
   1582 	{
   1583 		glw::GLintptr offset = (glw::GLintptr)NULL;
   1584 		glw::GLsizei  stride = sizeof(glw::GLint);
   1585 
   1586 		gl.vertexArrayVertexBuffers(m_vao, 2, 1, &m_bo_array_1, &offset, &stride);
   1587 
   1588 		if (glw::GLenum error = gl.getError())
   1589 		{
   1590 			m_context.getTestContext().getLog() << tcu::TestLog::Message
   1591 												<< "VertexArrayVertexBuffers has unexpectedly generated "
   1592 												<< glu::getErrorStr(error) << "error. Test fails.\n"
   1593 												<< tcu::TestLog::EndMessage;
   1594 
   1595 			return false;
   1596 		}
   1597 	}
   1598 	else
   1599 	{
   1600 		gl.vertexArrayVertexBuffer(m_vao, 2, m_bo_array_1, (glw::GLintptr)NULL, sizeof(glw::GLint));
   1601 
   1602 		if (glw::GLenum error = gl.getError())
   1603 		{
   1604 			m_context.getTestContext().getLog() << tcu::TestLog::Message
   1605 												<< "VertexArrayVertexBuffer has unexpectedly generated "
   1606 												<< glu::getErrorStr(error) << "error. Test fails.\n"
   1607 												<< tcu::TestLog::EndMessage;
   1608 
   1609 			return false;
   1610 		}
   1611 	}
   1612 
   1613 	gl.enableVertexAttribArray(2);
   1614 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   1615 
   1616 	gl.bindVertexArray(0);
   1617 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   1618 
   1619 	return true;
   1620 }
   1621 
   1622 /** @brief Prepare buffer object for test GLSL program transform feedback results.
   1623  */
   1624 void VertexBuffersTest::PrepareXFB()
   1625 {
   1626 	/* Shortcut for GL functionality */
   1627 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1628 
   1629 	/* Buffer creation. */
   1630 	gl.genBuffers(1, &m_bo_xfb);
   1631 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   1632 
   1633 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
   1634 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   1635 
   1636 	/* Preparing storage. */
   1637 	gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, 2 * sizeof(glw::GLint), NULL, GL_MAP_READ_BIT);
   1638 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed.");
   1639 
   1640 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
   1641 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
   1642 }
   1643 
   1644 /** @brief Draw test program, fetch transform feedback results and compare them with expected values.
   1645  *
   1646  *  @return True if expected results are equal to returned by XFB, false otherwise.
   1647  */
   1648 bool VertexBuffersTest::DrawAndCheck()
   1649 {
   1650 	/* Shortcut for GL functionality */
   1651 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1652 
   1653 	/* Setup state. */
   1654 	gl.useProgram(m_po);
   1655 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   1656 
   1657 	gl.bindVertexArray(m_vao);
   1658 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   1659 
   1660 	gl.beginTransformFeedback(GL_POINTS);
   1661 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   1662 
   1663 	/* Draw. */
   1664 	gl.drawArrays(GL_POINTS, 0, 2);
   1665 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   1666 
   1667 	/* State reset. */
   1668 	gl.endTransformFeedback();
   1669 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   1670 
   1671 	/* Result query. */
   1672 	glw::GLint* result_ptr = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   1673 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
   1674 
   1675 	glw::GLint result[2] = { result_ptr[0], result_ptr[1] };
   1676 
   1677 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   1678 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   1679 
   1680 	static const glw::GLint reference[2] = { 0 + 2 + 4, 1 + 3 + 5 };
   1681 
   1682 	/* Check result and return. */
   1683 	for (glw::GLint i = 0; i < 2; ++i)
   1684 	{
   1685 		if (reference[i] != result[i])
   1686 		{
   1687 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Result vector is equal to [" << result[0]
   1688 												<< ", " << result[1] << "], but [" << reference[0] << ", "
   1689 												<< reference[1] << "] was expected." << tcu::TestLog::EndMessage;
   1690 
   1691 			return false;
   1692 		}
   1693 	}
   1694 
   1695 	return true;
   1696 }
   1697 
   1698 /** @brief Clean GL objects. */
   1699 void VertexBuffersTest::Clean()
   1700 {
   1701 	/* Shortcut for GL functionality */
   1702 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1703 
   1704 	gl.useProgram(0);
   1705 
   1706 	if (m_po)
   1707 	{
   1708 		gl.deleteProgram(m_po);
   1709 
   1710 		m_po = 0;
   1711 	}
   1712 
   1713 	if (m_vao)
   1714 	{
   1715 		gl.deleteVertexArrays(1, &m_vao);
   1716 
   1717 		m_vao = 0;
   1718 	}
   1719 
   1720 	if (m_bo_array_0)
   1721 	{
   1722 		gl.deleteBuffers(1, &m_bo_array_0);
   1723 
   1724 		m_bo_array_0 = 0;
   1725 	}
   1726 
   1727 	if (m_bo_array_1)
   1728 	{
   1729 		gl.deleteBuffers(1, &m_bo_array_1);
   1730 
   1731 		m_bo_array_1 = 0;
   1732 	}
   1733 
   1734 	if (m_bo_xfb)
   1735 	{
   1736 		gl.deleteBuffers(1, &m_bo_xfb);
   1737 
   1738 		m_bo_xfb = 0;
   1739 	}
   1740 
   1741 	while (gl.getError())
   1742 		;
   1743 }
   1744 
   1745 const glw::GLchar VertexBuffersTest::s_vertex_shader[] = "#version 450\n"
   1746 														 "\n"
   1747 														 "in  int a_0;"
   1748 														 "in  int a_1;"
   1749 														 "in  int a_2;"
   1750 														 "\n"
   1751 														 "out int result;\n"
   1752 														 "\n"
   1753 														 "void main()\n"
   1754 														 "{\n"
   1755 														 "    gl_Position = vec4(1.0);\n"
   1756 														 "    result = a_0 + a_1 + a_2;"
   1757 														 "}\n";
   1758 
   1759 const glw::GLchar VertexBuffersTest::s_fragment_shader[] = "#version 450\n"
   1760 														   "\n"
   1761 														   "out vec4 color;\n"
   1762 														   "\n"
   1763 														   "void main()\n"
   1764 														   "{\n"
   1765 														   "    color = vec4(1.0);"
   1766 														   "}\n";
   1767 
   1768 /******************************** Vertex Array Object Attribute Format Test Implementation   ********************************/
   1769 
   1770 /** @brief Vertex Array Object Element Buffer Test constructor.
   1771  *
   1772  *  @param [in] context     OpenGL context.
   1773  */
   1774 AttributeFormatTest::AttributeFormatTest(deqp::Context& context)
   1775 	: deqp::TestCase(context, "vertex_arrays_attribute_format", "Vertex Array Object Attribute Format Test")
   1776 	, m_po(0)
   1777 	, m_vao(0)
   1778 	, m_bo_array(0)
   1779 	, m_bo_xfb(0)
   1780 {
   1781 	/* Intentionally left blank. */
   1782 }
   1783 
   1784 /** @brief Iterate Vertex Array Object Enable Disable Attributes Test cases.
   1785  *
   1786  *  @return Iteration result.
   1787  */
   1788 tcu::TestNode::IterateResult AttributeFormatTest::iterate()
   1789 {
   1790 	/* Shortcut for GL functionality. */
   1791 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1792 
   1793 	/* Get context setup. */
   1794 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
   1795 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
   1796 
   1797 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
   1798 	{
   1799 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
   1800 
   1801 		return STOP;
   1802 	}
   1803 
   1804 	/* Running tests. */
   1805 	bool is_ok	= true;
   1806 	bool is_error = false;
   1807 
   1808 	try
   1809 	{
   1810 		PrepareXFB();
   1811 
   1812 		/* Test floating function. */
   1813 		for (glw::GLuint i = 1; i <= 4 /* max size */; ++i)
   1814 		{
   1815 			PrepareProgram(i, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
   1816 
   1817 			is_ok &= PrepareVAO<glw::GLfloat>(i, GL_FLOAT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
   1818 			is_ok &= DrawAndCheck<glw::GLfloat>(i, false);
   1819 
   1820 			CleanVAO();
   1821 
   1822 			is_ok &= PrepareVAO<glw::GLbyte>(i, GL_BYTE, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
   1823 			is_ok &= DrawAndCheck<glw::GLfloat>(i, false);
   1824 
   1825 			CleanVAO();
   1826 
   1827 			is_ok &= PrepareVAO<glw::GLbyte>(i, GL_BYTE, true, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
   1828 			is_ok &= DrawAndCheck<glw::GLfloat>(i, true);
   1829 
   1830 			CleanVAO();
   1831 
   1832 			is_ok &= PrepareVAO<glw::GLubyte>(i, GL_UNSIGNED_BYTE, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
   1833 			is_ok &= DrawAndCheck<glw::GLfloat>(i, false);
   1834 
   1835 			CleanVAO();
   1836 
   1837 			is_ok &= PrepareVAO<glw::GLshort>(i, GL_SHORT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
   1838 			is_ok &= DrawAndCheck<glw::GLfloat>(i, false);
   1839 
   1840 			CleanVAO();
   1841 
   1842 			is_ok &= PrepareVAO<glw::GLushort>(i, GL_UNSIGNED_SHORT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
   1843 			is_ok &= DrawAndCheck<glw::GLfloat>(i, false);
   1844 
   1845 			CleanVAO();
   1846 
   1847 			is_ok &= PrepareVAO<glw::GLint>(i, GL_INT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
   1848 			is_ok &= DrawAndCheck<glw::GLfloat>(i, false);
   1849 
   1850 			CleanVAO();
   1851 
   1852 			is_ok &= PrepareVAO<glw::GLuint>(i, GL_UNSIGNED_INT, false, ATTRIBUTE_FORMAT_FUNCTION_FLOAT);
   1853 			is_ok &= DrawAndCheck<glw::GLfloat>(i, false);
   1854 
   1855 			CleanVAO();
   1856 
   1857 			CleanProgram();
   1858 		}
   1859 
   1860 		for (glw::GLuint i = 1; i <= 2 /* max size */; ++i)
   1861 		{
   1862 			PrepareProgram(i, ATTRIBUTE_FORMAT_FUNCTION_DOUBLE);
   1863 
   1864 			is_ok &= PrepareVAO<glw::GLdouble>(i, GL_DOUBLE, false, ATTRIBUTE_FORMAT_FUNCTION_DOUBLE);
   1865 			is_ok &= DrawAndCheck<glw::GLdouble>(i, false);
   1866 
   1867 			CleanProgram();
   1868 			CleanVAO();
   1869 		}
   1870 
   1871 		for (glw::GLuint i = 1; i <= 4 /* max size */; ++i)
   1872 		{
   1873 			PrepareProgram(i, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
   1874 
   1875 			is_ok &= PrepareVAO<glw::GLbyte>(i, GL_BYTE, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
   1876 			is_ok &= DrawAndCheck<glw::GLint>(i, false);
   1877 
   1878 			CleanVAO();
   1879 
   1880 			is_ok &= PrepareVAO<glw::GLubyte>(i, GL_UNSIGNED_BYTE, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
   1881 			is_ok &= DrawAndCheck<glw::GLint>(i, false);
   1882 
   1883 			CleanVAO();
   1884 
   1885 			is_ok &= PrepareVAO<glw::GLshort>(i, GL_SHORT, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
   1886 			is_ok &= DrawAndCheck<glw::GLint>(i, false);
   1887 
   1888 			CleanVAO();
   1889 
   1890 			is_ok &= PrepareVAO<glw::GLushort>(i, GL_UNSIGNED_SHORT, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
   1891 			is_ok &= DrawAndCheck<glw::GLint>(i, false);
   1892 
   1893 			CleanVAO();
   1894 
   1895 			is_ok &= PrepareVAO<glw::GLint>(i, GL_INT, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
   1896 			is_ok &= DrawAndCheck<glw::GLint>(i, false);
   1897 
   1898 			CleanVAO();
   1899 
   1900 			is_ok &= PrepareVAO<glw::GLuint>(i, GL_UNSIGNED_INT, false, ATTRIBUTE_FORMAT_FUNCTION_INTEGER);
   1901 			is_ok &= DrawAndCheck<glw::GLint>(i, false);
   1902 
   1903 			CleanVAO();
   1904 
   1905 			CleanProgram();
   1906 		}
   1907 	}
   1908 	catch (...)
   1909 	{
   1910 		is_ok	= false;
   1911 		is_error = true;
   1912 	}
   1913 
   1914 	/* Cleanup. */
   1915 	CleanProgram();
   1916 	CleanVAO();
   1917 	CleanXFB();
   1918 
   1919 	/* Errors clean up. */
   1920 	while (gl.getError())
   1921 		;
   1922 
   1923 	/* Result's setup. */
   1924 	if (is_ok)
   1925 	{
   1926 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1927 	}
   1928 	else
   1929 	{
   1930 		if (is_error)
   1931 		{
   1932 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   1933 		}
   1934 		else
   1935 		{
   1936 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1937 		}
   1938 	}
   1939 
   1940 	return STOP;
   1941 }
   1942 
   1943 /** @brief Build test's GLSL program.
   1944  *
   1945  *  @note The function may throw if unexpected error has occured.
   1946  */
   1947 void AttributeFormatTest::PrepareProgram(glw::GLint size, AtributeFormatFunctionType function_selector)
   1948 {
   1949 	/* Shortcut for GL functionality */
   1950 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   1951 
   1952 	struct Shader
   1953 	{
   1954 		glw::GLchar const* source[3];
   1955 		glw::GLuint const  count;
   1956 		glw::GLenum const  type;
   1957 		glw::GLuint		   id;
   1958 	} shader[] = { { { s_vertex_shader_head, s_vertex_shader_declaration[function_selector][size - 1],
   1959 					   s_vertex_shader_body },
   1960 					 3,
   1961 					 GL_VERTEX_SHADER,
   1962 					 0 },
   1963 				   { { s_fragment_shader, DE_NULL, DE_NULL }, 1, GL_FRAGMENT_SHADER, 0 } };
   1964 
   1965 	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
   1966 
   1967 	try
   1968 	{
   1969 		/* Create program. */
   1970 		m_po = gl.createProgram();
   1971 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
   1972 
   1973 		/* Shader compilation. */
   1974 
   1975 		for (glw::GLuint i = 0; i < shader_count; ++i)
   1976 		{
   1977 			{
   1978 				shader[i].id = gl.createShader(shader[i].type);
   1979 
   1980 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
   1981 
   1982 				gl.attachShader(m_po, shader[i].id);
   1983 
   1984 				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
   1985 
   1986 				gl.shaderSource(shader[i].id, shader[i].count, shader[i].source, NULL);
   1987 
   1988 				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
   1989 
   1990 				gl.compileShader(shader[i].id);
   1991 
   1992 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
   1993 
   1994 				glw::GLint status = GL_FALSE;
   1995 
   1996 				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
   1997 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
   1998 
   1999 				if (GL_FALSE == status)
   2000 				{
   2001 					glw::GLint log_size = 0;
   2002 					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
   2003 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
   2004 
   2005 					glw::GLchar* log_text = new glw::GLchar[log_size];
   2006 
   2007 					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
   2008 
   2009 					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
   2010 														<< "Shader type: " << glu::getShaderTypeStr(shader[i].type)
   2011 														<< "\n"
   2012 														<< "Shader compilation error log:\n"
   2013 														<< log_text << "\n"
   2014 														<< "Shader source code:\n"
   2015 														<< shader[i].source << "\n"
   2016 														<< tcu::TestLog::EndMessage;
   2017 
   2018 					delete[] log_text;
   2019 
   2020 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
   2021 
   2022 					throw 0;
   2023 				}
   2024 			}
   2025 		}
   2026 
   2027 		/* Transform Feedback setup. */
   2028 		static const glw::GLchar* xfb_varying = "result";
   2029 
   2030 		gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS);
   2031 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
   2032 
   2033 		/* Link. */
   2034 		gl.linkProgram(m_po);
   2035 
   2036 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
   2037 
   2038 		glw::GLint status = GL_FALSE;
   2039 
   2040 		gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
   2041 
   2042 		if (GL_TRUE == status)
   2043 		{
   2044 			for (glw::GLuint i = 0; i < shader_count; ++i)
   2045 			{
   2046 				if (shader[i].id)
   2047 				{
   2048 					gl.detachShader(m_po, shader[i].id);
   2049 
   2050 					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
   2051 				}
   2052 			}
   2053 		}
   2054 		else
   2055 		{
   2056 			glw::GLint log_size = 0;
   2057 
   2058 			gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
   2059 
   2060 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
   2061 
   2062 			glw::GLchar* log_text = new glw::GLchar[log_size];
   2063 
   2064 			gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
   2065 
   2066 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
   2067 												<< log_text << "\n"
   2068 												<< tcu::TestLog::EndMessage;
   2069 
   2070 			delete[] log_text;
   2071 
   2072 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
   2073 
   2074 			throw 0;
   2075 		}
   2076 	}
   2077 	catch (...)
   2078 	{
   2079 		if (m_po)
   2080 		{
   2081 			gl.deleteProgram(m_po);
   2082 
   2083 			m_po = 0;
   2084 		}
   2085 	}
   2086 
   2087 	for (glw::GLuint i = 0; i < shader_count; ++i)
   2088 	{
   2089 		if (0 != shader[i].id)
   2090 		{
   2091 			gl.deleteShader(shader[i].id);
   2092 
   2093 			shader[i].id = 0;
   2094 		}
   2095 	}
   2096 
   2097 	if (0 == m_po)
   2098 	{
   2099 		throw 0;
   2100 	}
   2101 }
   2102 
   2103 template <>
   2104 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLuint>()
   2105 {
   2106 	return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLuint) - 4 /* 1.0 / 16.0 */));
   2107 }
   2108 
   2109 template <>
   2110 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLushort>()
   2111 {
   2112 	return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLushort) - 4 /* 1.0 / 16.0 */));
   2113 }
   2114 
   2115 template <>
   2116 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLubyte>()
   2117 {
   2118 	return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLubyte) - 4 /* 1.0 / 16.0 */));
   2119 }
   2120 
   2121 template <>
   2122 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLint>()
   2123 {
   2124 	return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLint) - 4 /* 1.0 / 16.0 */ - 1 /* sign bit */));
   2125 }
   2126 
   2127 template <>
   2128 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLshort>()
   2129 {
   2130 	return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLshort) - 4 /* 1.0 / 16.0 */ - 1 /* sign bit */));
   2131 }
   2132 
   2133 template <>
   2134 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor<glw::GLbyte>()
   2135 {
   2136 	return std::pow(2.0, (glw::GLdouble)(CHAR_BIT * sizeof(glw::GLbyte) - 4 /* 1.0 / 16.0 */ - 1 /* sign bit */));
   2137 }
   2138 
   2139 template <typename T>
   2140 glw::GLdouble AttributeFormatTest::NormalizationScaleFactor()
   2141 {
   2142 	return 1.0; /* Rest of the types cannot be normalized. */
   2143 }
   2144 
   2145 /** @brief Prepare vertex array object for the test of VertexArrayAttrib*Format function.
   2146  *
   2147  *  @param [in] size                Size passed to VertexArrayAttrib*Format.
   2148  *  @param [in] type_gl_name        Type passed to VertexArrayAttrib*Format.
   2149  *  @param [in] function_selector   Selects one of VertexArrayAttrib*Format functions.
   2150  *
   2151  *  @return True if function VertexArrayAttrib*Format does not generate any error.
   2152  */
   2153 template <typename T>
   2154 bool AttributeFormatTest::PrepareVAO(glw::GLint size, glw::GLenum type_gl_name, bool normalized,
   2155 									 AtributeFormatFunctionType function_selector)
   2156 {
   2157 	/* Shortcut for GL functionality */
   2158 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2159 
   2160 	/* VAO creation. */
   2161 	gl.genVertexArrays(1, &m_vao);
   2162 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   2163 
   2164 	gl.bindVertexArray(m_vao);
   2165 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   2166 
   2167 	/* Array buffer 0 creation. */
   2168 
   2169 	const glw::GLdouble scale = normalized ? NormalizationScaleFactor<T>() : 1.0;
   2170 
   2171 	const T array_data[16] = { (T)(0.0 * scale),  (T)(1.0 * scale),  (T)(2.0 * scale),  (T)(3.0 * scale),
   2172 							   (T)(4.0 * scale),  (T)(5.0 * scale),  (T)(6.0 * scale),  (T)(7.0 * scale),
   2173 							   (T)(8.0 * scale),  (T)(9.0 * scale),  (T)(10.0 * scale), (T)(11.0 * scale),
   2174 							   (T)(12.0 * scale), (T)(13.0 * scale), (T)(14.0 * scale), (T)(15.0 * scale) };
   2175 
   2176 	gl.genBuffers(1, &m_bo_array);
   2177 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   2178 
   2179 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array);
   2180 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   2181 
   2182 	gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data), array_data, GL_STATIC_DRAW);
   2183 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   2184 
   2185 	/* Attribute setup. */
   2186 	gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_0"), 0);
   2187 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed.");
   2188 
   2189 	gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a_1"), 1);
   2190 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed.");
   2191 
   2192 	/* Tested attribute format setup. */
   2193 	switch (function_selector)
   2194 	{
   2195 	case ATTRIBUTE_FORMAT_FUNCTION_FLOAT:
   2196 		gl.vertexArrayAttribFormat(m_vao, gl.getAttribLocation(m_po, "a_0"), size, type_gl_name, normalized, 0);
   2197 		gl.vertexArrayAttribFormat(m_vao, gl.getAttribLocation(m_po, "a_1"), size, type_gl_name, normalized, 0);
   2198 		break;
   2199 
   2200 	case ATTRIBUTE_FORMAT_FUNCTION_DOUBLE:
   2201 		gl.vertexArrayAttribLFormat(m_vao, gl.getAttribLocation(m_po, "a_0"), size, type_gl_name, 0);
   2202 		gl.vertexArrayAttribLFormat(m_vao, gl.getAttribLocation(m_po, "a_1"), size, type_gl_name, 0);
   2203 		break;
   2204 
   2205 	case ATTRIBUTE_FORMAT_FUNCTION_INTEGER:
   2206 		gl.vertexArrayAttribIFormat(m_vao, gl.getAttribLocation(m_po, "a_0"), size, type_gl_name, 0);
   2207 		gl.vertexArrayAttribIFormat(m_vao, gl.getAttribLocation(m_po, "a_1"), size, type_gl_name, 0);
   2208 		break;
   2209 	default:
   2210 		throw 0;
   2211 	}
   2212 
   2213 	if (glw::GLenum error = gl.getError())
   2214 	{
   2215 		m_context.getTestContext().getLog()
   2216 			<< tcu::TestLog::Message
   2217 			<< ((ATTRIBUTE_FORMAT_FUNCTION_FLOAT == function_selector) ?
   2218 					"VertexArrayAttribFormat" :
   2219 					((ATTRIBUTE_FORMAT_FUNCTION_DOUBLE == function_selector) ?
   2220 						 "VertexArrayAttribLFormat" :
   2221 						 ((ATTRIBUTE_FORMAT_FUNCTION_INTEGER == function_selector) ? "VertexArrayAttribIFormat" :
   2222 																					 "VertexArrayAttrib?Format")))
   2223 			<< " has unexpectedly generated " << glu::getErrorStr(error) << "error for test with size = " << size
   2224 			<< ", type = " << glu::getTypeStr(type_gl_name)
   2225 			<< ((ATTRIBUTE_FORMAT_FUNCTION_FLOAT == function_selector) ?
   2226 					(normalized ? ", which was normalized." : ", which was not normalized.") :
   2227 					".")
   2228 			<< " Test fails.\n"
   2229 			<< tcu::TestLog::EndMessage;
   2230 
   2231 		return false;
   2232 	}
   2233 
   2234 	gl.bindVertexBuffer(0, m_bo_array, 0, static_cast<glw::GLsizei>(sizeof(T) * size * 2));
   2235 	gl.bindVertexBuffer(1, m_bo_array, (glw::GLintptr)((T*)NULL + size),
   2236 						static_cast<glw::GLsizei>(sizeof(T) * size * 2));
   2237 
   2238 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   2239 
   2240 	gl.enableVertexAttribArray(0);
   2241 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   2242 
   2243 	gl.enableVertexAttribArray(1);
   2244 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   2245 
   2246 	gl.bindVertexArray(0);
   2247 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   2248 
   2249 	return true;
   2250 }
   2251 
   2252 /** @brief Prepare buffer object for test GLSL program transform feedback results.
   2253  */
   2254 void AttributeFormatTest::PrepareXFB()
   2255 {
   2256 	/* Shortcut for GL functionality */
   2257 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2258 
   2259 	/* Buffer creation. */
   2260 	gl.genBuffers(1, &m_bo_xfb);
   2261 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   2262 
   2263 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
   2264 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   2265 
   2266 	/* Calculating maximum size. */
   2267 	glw::GLsizei size = static_cast<glw::GLsizei>(
   2268 		de::max(sizeof(glw::GLubyte),
   2269 				de::max(sizeof(glw::GLbyte),
   2270 						de::max(sizeof(glw::GLushort),
   2271 								de::max(sizeof(glw::GLshort),
   2272 										de::max(sizeof(glw::GLhalf),
   2273 												de::max(sizeof(glw::GLint),
   2274 														de::max(sizeof(glw::GLuint),
   2275 																de::max(sizeof(glw::GLfixed),
   2276 																		de::max(sizeof(glw::GLfloat),
   2277 																				sizeof(glw::GLdouble)))))))))) *
   2278 		4 /* maximum number of components */);
   2279 
   2280 	/* Preparing storage. */
   2281 	gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, size, NULL, GL_MAP_READ_BIT);
   2282 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed.");
   2283 
   2284 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
   2285 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
   2286 }
   2287 
   2288 template <>
   2289 bool AttributeFormatTest::compare<glw::GLfloat>(glw::GLfloat a, glw::GLfloat b)
   2290 {
   2291 	if (de::abs(a - b) < 0.03125)
   2292 	{
   2293 		return true;
   2294 	}
   2295 
   2296 	return false;
   2297 }
   2298 
   2299 template <>
   2300 bool AttributeFormatTest::compare<glw::GLdouble>(glw::GLdouble a, glw::GLdouble b)
   2301 {
   2302 	if (de::abs(a - b) < 0.03125)
   2303 	{
   2304 		return true;
   2305 	}
   2306 
   2307 	return false;
   2308 }
   2309 
   2310 template <typename T>
   2311 bool AttributeFormatTest::compare(T a, T b)
   2312 {
   2313 	return (a == b);
   2314 }
   2315 
   2316 /** @brief Draw test program, fetch transform feedback results and compare them with expected values.
   2317  *
   2318  *  @param [in] size         Count of elements of the XFB vector is expected.
   2319  *  @param [in] normalized   Normalized values are expected.
   2320  *
   2321  *  @return True if expected results are equal to returned by XFB, false otherwise.
   2322  */
   2323 template <typename T>
   2324 bool AttributeFormatTest::DrawAndCheck(glw::GLint size, bool normalized)
   2325 {
   2326 	/* Shortcut for GL functionality */
   2327 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2328 
   2329 	/* Setup state. */
   2330 	gl.useProgram(m_po);
   2331 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   2332 
   2333 	gl.bindVertexArray(m_vao);
   2334 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   2335 
   2336 	/* Draw. */
   2337 	gl.beginTransformFeedback(GL_POINTS);
   2338 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   2339 
   2340 	gl.drawArrays(GL_POINTS, 0, 2);
   2341 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   2342 
   2343 	gl.endTransformFeedback();
   2344 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   2345 
   2346 	/* Result query. */
   2347 	T* result_ptr = (T*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   2348 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
   2349 
   2350 	T result[8] = { 0 };
   2351 
   2352 	for (glw::GLint i = 0; i < size * 2 /* two points */; ++i)
   2353 	{
   2354 		result[i] = result_ptr[i];
   2355 	}
   2356 
   2357 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   2358 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   2359 
   2360 	const glw::GLdouble scale = normalized ? (1.0 / 16.0) /* Floating point scalling factor. */ : 1.0;
   2361 
   2362 	const T array_data[16] = { (T)(0.0 * scale),  (T)(1.0 * scale),  (T)(2.0 * scale),  (T)(3.0 * scale),
   2363 							   (T)(4.0 * scale),  (T)(5.0 * scale),  (T)(6.0 * scale),  (T)(7.0 * scale),
   2364 							   (T)(8.0 * scale),  (T)(9.0 * scale),  (T)(10.0 * scale), (T)(11.0 * scale),
   2365 							   (T)(12.0 * scale), (T)(13.0 * scale), (T)(14.0 * scale), (T)(15.0 * scale) };
   2366 
   2367 	T reference[8] = { 0 };
   2368 
   2369 	for (glw::GLint i = 0; i < 2 /* two points */; ++i)
   2370 	{
   2371 		for (glw::GLint j = 0; j < size /* size components */; ++j)
   2372 		{
   2373 			reference[i * size + j] = array_data[i * size * 2 + j] + array_data[i * size * 2 + j + size];
   2374 		}
   2375 	}
   2376 
   2377 	/* Check result and return. */
   2378 	for (glw::GLint i = 0; i < size * 2 /* two points */; ++i)
   2379 	{
   2380 		if (!AttributeFormatTest::compare<T>(reference[i], result[i]))
   2381 		{
   2382 			std::string reference_str = "[ ";
   2383 
   2384 			for (glw::GLint j = 0; j < size * 2 /* two points */; ++j)
   2385 			{
   2386 				std::stringstream ss;
   2387 
   2388 				ss << reference[j];
   2389 
   2390 				reference_str.append(ss.str());
   2391 
   2392 				if (j < size * 2 - 1 /* if it is not the last value */)
   2393 				{
   2394 					reference_str.append(", ");
   2395 				}
   2396 				else
   2397 				{
   2398 					reference_str.append(" ]");
   2399 				}
   2400 			}
   2401 
   2402 			std::string result_str = "[ ";
   2403 
   2404 			for (glw::GLint j = 0; j < size * 2 /* two points */; ++j)
   2405 			{
   2406 				std::stringstream ss;
   2407 
   2408 				ss << result[j];
   2409 
   2410 				result_str.append(ss.str());
   2411 
   2412 				if (j < size * 2 - 1 /* if it is not the last value */)
   2413 				{
   2414 					result_str.append(", ");
   2415 				}
   2416 				else
   2417 				{
   2418 					result_str.append(" ]");
   2419 				}
   2420 			}
   2421 
   2422 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Result vector is equal to "
   2423 												<< result_str.c_str() << ", but " << reference_str.c_str()
   2424 												<< " was expected." << tcu::TestLog::EndMessage;
   2425 
   2426 			return false;
   2427 		}
   2428 	}
   2429 
   2430 	return true;
   2431 }
   2432 
   2433 /** @brief Clean GLSL program object. */
   2434 void AttributeFormatTest::CleanProgram()
   2435 {
   2436 	/* Shortcut for GL functionality */
   2437 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2438 
   2439 	gl.useProgram(0);
   2440 
   2441 	if (m_po)
   2442 	{
   2443 		gl.deleteProgram(m_po);
   2444 
   2445 		m_po = 0;
   2446 	}
   2447 }
   2448 
   2449 /** @brief Clean Vertex Array Object and related buffer. */
   2450 void AttributeFormatTest::CleanVAO()
   2451 {
   2452 	/* Shortcut for GL functionality */
   2453 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2454 
   2455 	if (m_vao)
   2456 	{
   2457 		gl.deleteVertexArrays(1, &m_vao);
   2458 
   2459 		m_vao = 0;
   2460 	}
   2461 
   2462 	if (m_bo_array)
   2463 	{
   2464 		gl.deleteBuffers(1, &m_bo_array);
   2465 
   2466 		m_bo_array = 0;
   2467 	}
   2468 }
   2469 
   2470 /** @brief Clean GL objects related to transform feedback. */
   2471 void AttributeFormatTest::CleanXFB()
   2472 {
   2473 	/* Shortcut for GL functionality */
   2474 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2475 
   2476 	if (m_bo_xfb)
   2477 	{
   2478 		gl.deleteBuffers(1, &m_bo_xfb);
   2479 
   2480 		m_bo_xfb = 0;
   2481 	}
   2482 
   2483 	while (gl.getError())
   2484 		;
   2485 }
   2486 
   2487 const glw::GLchar* AttributeFormatTest::s_vertex_shader_head = "#version 450\n"
   2488 															   "\n";
   2489 
   2490 const glw::GLchar* AttributeFormatTest::s_vertex_shader_body = "\n"
   2491 															   "void main()\n"
   2492 															   "{\n"
   2493 															   "    gl_Position = vec4(1.0);\n"
   2494 															   "    result = a_0 + a_1;"
   2495 															   "}\n";
   2496 
   2497 const glw::GLchar* AttributeFormatTest::s_vertex_shader_declaration[ATTRIBUTE_FORMAT_FUNCTION_COUNT]
   2498 																   [4 /* sizes count */] = { {
   2499 																								 "in  float a_0;"
   2500 																								 "in  float a_1;"
   2501 																								 "out float result;\n",
   2502 
   2503 																								 "in  vec2 a_0;"
   2504 																								 "in  vec2 a_1;"
   2505 																								 "out vec2 result;\n",
   2506 
   2507 																								 "in  vec3 a_0;"
   2508 																								 "in  vec3 a_1;"
   2509 																								 "out vec3 result;\n",
   2510 
   2511 																								 "in  vec4 a_0;"
   2512 																								 "in  vec4 a_1;"
   2513 																								 "out vec4 result;\n",
   2514 																							 },
   2515 																							 {
   2516 																								 "in  double a_0;"
   2517 																								 "in  double a_1;"
   2518 																								 "out double result;\n",
   2519 
   2520 																								 "in  dvec2 a_0;"
   2521 																								 "in  dvec2 a_1;"
   2522 																								 "out dvec2 result;\n",
   2523 
   2524 																								 "in  dvec3 a_0;"
   2525 																								 "in  dvec3 a_1;"
   2526 																								 "out dvec3 result;\n",
   2527 
   2528 																								 "in  dvec4 a_0;"
   2529 																								 "in  dvec4 a_1;"
   2530 																								 "out dvec4 result;\n",
   2531 																							 },
   2532 																							 {
   2533 																								 "in  int a_0;"
   2534 																								 "in  int a_1;"
   2535 																								 "out int result;\n",
   2536 
   2537 																								 "in  ivec2 a_0;"
   2538 																								 "in  ivec2 a_1;"
   2539 																								 "out ivec2 result;\n",
   2540 
   2541 																								 "in  ivec3 a_0;"
   2542 																								 "in  ivec3 a_1;"
   2543 																								 "out ivec3 result;\n",
   2544 
   2545 																								 "in  ivec4 a_0;"
   2546 																								 "in  ivec4 a_1;"
   2547 																								 "out ivec4 result;\n",
   2548 																							 } };
   2549 
   2550 const glw::GLchar* AttributeFormatTest::s_fragment_shader = "#version 450\n"
   2551 															"\n"
   2552 															"out vec4 color;\n"
   2553 															"\n"
   2554 															"void main()\n"
   2555 															"{\n"
   2556 															"    color = vec4(1.0);"
   2557 															"}\n";
   2558 
   2559 /******************************** Vertex Array Object Attribute Binding Test Implementation   ********************************/
   2560 
   2561 /** @brief Attribute Binding Test constructor.
   2562  *
   2563  *  @param [in] context     OpenGL context.
   2564  */
   2565 AttributeBindingTest::AttributeBindingTest(deqp::Context& context)
   2566 	: deqp::TestCase(context, "vertex_arrays_attribute_binding", "Vertex Array Objects Attribute Binding Test")
   2567 	, m_po(0)
   2568 	, m_vao(0)
   2569 	, m_bo_array(0)
   2570 	, m_bo_xfb(0)
   2571 {
   2572 	/* Intentionally left blank. */
   2573 }
   2574 
   2575 /** @brief Iterate Attribute Binding Test cases.
   2576  *
   2577  *  @return Iteration result.
   2578  */
   2579 tcu::TestNode::IterateResult AttributeBindingTest::iterate()
   2580 {
   2581 	/* Shortcut for GL functionality. */
   2582 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2583 
   2584 	/* Get context setup. */
   2585 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
   2586 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
   2587 
   2588 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
   2589 	{
   2590 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
   2591 
   2592 		return STOP;
   2593 	}
   2594 
   2595 	/* Running tests. */
   2596 	bool is_ok	= true;
   2597 	bool is_error = false;
   2598 
   2599 	try
   2600 	{
   2601 		PrepareProgram();
   2602 		is_ok &= PrepareVAO();
   2603 		PrepareXFB();
   2604 		is_ok &= DrawAndCheck();
   2605 	}
   2606 	catch (...)
   2607 	{
   2608 		is_ok	= false;
   2609 		is_error = true;
   2610 	}
   2611 
   2612 	/* Cleanup. */
   2613 	Clean();
   2614 
   2615 	/* Errors clean up. */
   2616 	while (gl.getError())
   2617 		;
   2618 
   2619 	/* Result's setup. */
   2620 	if (is_ok)
   2621 	{
   2622 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   2623 	}
   2624 	else
   2625 	{
   2626 		if (is_error)
   2627 		{
   2628 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   2629 		}
   2630 		else
   2631 		{
   2632 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   2633 		}
   2634 	}
   2635 
   2636 	return STOP;
   2637 }
   2638 
   2639 /** @brief Build test's GLSL program.
   2640  *
   2641  *  @note The function may throw if unexpected error has occured.
   2642  */
   2643 void AttributeBindingTest::PrepareProgram()
   2644 {
   2645 	/* Shortcut for GL functionality */
   2646 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2647 
   2648 	struct Shader
   2649 	{
   2650 		glw::GLchar const* const source;
   2651 		glw::GLenum const		 type;
   2652 		glw::GLuint				 id;
   2653 	} shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };
   2654 
   2655 	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
   2656 
   2657 	try
   2658 	{
   2659 		/* Create program. */
   2660 		m_po = gl.createProgram();
   2661 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
   2662 
   2663 		/* Shader compilation. */
   2664 
   2665 		for (glw::GLuint i = 0; i < shader_count; ++i)
   2666 		{
   2667 			if (DE_NULL != shader[i].source)
   2668 			{
   2669 				shader[i].id = gl.createShader(shader[i].type);
   2670 
   2671 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
   2672 
   2673 				gl.attachShader(m_po, shader[i].id);
   2674 
   2675 				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
   2676 
   2677 				gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
   2678 
   2679 				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
   2680 
   2681 				gl.compileShader(shader[i].id);
   2682 
   2683 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
   2684 
   2685 				glw::GLint status = GL_FALSE;
   2686 
   2687 				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
   2688 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
   2689 
   2690 				if (GL_FALSE == status)
   2691 				{
   2692 					glw::GLint log_size = 0;
   2693 					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
   2694 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
   2695 
   2696 					glw::GLchar* log_text = new glw::GLchar[log_size];
   2697 
   2698 					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
   2699 
   2700 					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
   2701 														<< "Shader type: " << glu::getShaderTypeStr(shader[i].type)
   2702 														<< "\n"
   2703 														<< "Shader compilation error log:\n"
   2704 														<< log_text << "\n"
   2705 														<< "Shader source code:\n"
   2706 														<< shader[i].source << "\n"
   2707 														<< tcu::TestLog::EndMessage;
   2708 
   2709 					delete[] log_text;
   2710 
   2711 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
   2712 
   2713 					throw 0;
   2714 				}
   2715 			}
   2716 		}
   2717 
   2718 		/* Binding attributes. */
   2719 		gl.bindAttribLocation(m_po, 0, "a_0");
   2720 		gl.bindAttribLocation(m_po, 1, "a_1");
   2721 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindAttribLocation call failed.");
   2722 
   2723 		/* Transform Feedback setup. */
   2724 		static const glw::GLchar* xfb_varying = "result";
   2725 		gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS);
   2726 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
   2727 
   2728 		/* Link. */
   2729 		gl.linkProgram(m_po);
   2730 
   2731 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
   2732 
   2733 		glw::GLint status = GL_FALSE;
   2734 
   2735 		gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
   2736 
   2737 		if (GL_TRUE == status)
   2738 		{
   2739 			for (glw::GLuint i = 0; i < shader_count; ++i)
   2740 			{
   2741 				if (shader[i].id)
   2742 				{
   2743 					gl.detachShader(m_po, shader[i].id);
   2744 
   2745 					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
   2746 				}
   2747 			}
   2748 		}
   2749 		else
   2750 		{
   2751 			glw::GLint log_size = 0;
   2752 
   2753 			gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
   2754 
   2755 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
   2756 
   2757 			glw::GLchar* log_text = new glw::GLchar[log_size];
   2758 
   2759 			gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
   2760 
   2761 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
   2762 												<< log_text << "\n"
   2763 												<< tcu::TestLog::EndMessage;
   2764 
   2765 			delete[] log_text;
   2766 
   2767 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
   2768 
   2769 			throw 0;
   2770 		}
   2771 	}
   2772 	catch (...)
   2773 	{
   2774 		if (m_po)
   2775 		{
   2776 			gl.deleteProgram(m_po);
   2777 
   2778 			m_po = 0;
   2779 		}
   2780 	}
   2781 
   2782 	for (glw::GLuint i = 0; i < shader_count; ++i)
   2783 	{
   2784 		if (0 != shader[i].id)
   2785 		{
   2786 			gl.deleteShader(shader[i].id);
   2787 
   2788 			shader[i].id = 0;
   2789 		}
   2790 	}
   2791 
   2792 	if (0 == m_po)
   2793 	{
   2794 		throw 0;
   2795 	}
   2796 }
   2797 
   2798 /** @brief Prepare vertex array object for the test.
   2799  *
   2800  *  @return True if function VertexArrayAttribBinding does not generate any error.
   2801  */
   2802 bool AttributeBindingTest::PrepareVAO()
   2803 {
   2804 	/* Shortcut for GL functionality */
   2805 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2806 
   2807 	/* VAO creation. */
   2808 	gl.genVertexArrays(1, &m_vao);
   2809 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   2810 
   2811 	gl.bindVertexArray(m_vao);
   2812 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   2813 
   2814 	/* Array buffer creation. */
   2815 	glw::GLint array_data[2] = { 1, 0 };
   2816 
   2817 	gl.genBuffers(1, &m_bo_array);
   2818 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   2819 
   2820 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array);
   2821 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   2822 
   2823 	gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data), array_data, GL_STATIC_DRAW);
   2824 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   2825 
   2826 	gl.vertexAttribIPointer(0, 1, GL_INT, sizeof(glw::GLint) * 2, NULL);
   2827 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer call failed.");
   2828 
   2829 	gl.vertexAttribIPointer(1, 1, GL_INT, sizeof(glw::GLint) * 2, (glw::GLvoid*)((glw::GLint*)NULL + 1));
   2830 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIPointer call failed.");
   2831 
   2832 	gl.enableVertexAttribArray(0);
   2833 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   2834 
   2835 	gl.enableVertexAttribArray(1);
   2836 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   2837 
   2838 	gl.vertexArrayAttribBinding(m_vao, 0, 1);
   2839 	gl.vertexArrayAttribBinding(m_vao, 1, 0);
   2840 
   2841 	if (glw::GLenum error = gl.getError())
   2842 	{
   2843 		m_context.getTestContext().getLog() << tcu::TestLog::Message
   2844 											<< "VertexArrayAttribBinding has unexpectedly generated "
   2845 											<< glu::getErrorStr(error) << "error. Test fails.\n"
   2846 											<< tcu::TestLog::EndMessage;
   2847 
   2848 		return false;
   2849 	}
   2850 
   2851 	return true;
   2852 }
   2853 
   2854 /** @brief Prepare buffer object for test GLSL program transform feedback results.
   2855  */
   2856 void AttributeBindingTest::PrepareXFB()
   2857 {
   2858 	/* Shortcut for GL functionality */
   2859 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2860 
   2861 	/* Buffer creation. */
   2862 	gl.genBuffers(1, &m_bo_xfb);
   2863 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   2864 
   2865 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
   2866 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   2867 
   2868 	/* Preparing storage. */
   2869 	gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, 2 * sizeof(glw::GLint), NULL, GL_MAP_READ_BIT);
   2870 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed.");
   2871 
   2872 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
   2873 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
   2874 }
   2875 
   2876 /** @brief Draw test program, fetch transform feedback results and compare them with expected values.
   2877  *
   2878  *  @return True if expected results are equal to returned by XFB, false otherwise.
   2879  */
   2880 bool AttributeBindingTest::DrawAndCheck()
   2881 {
   2882 	/* Shortcut for GL functionality */
   2883 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2884 
   2885 	/* Setup state. */
   2886 	gl.useProgram(m_po);
   2887 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   2888 
   2889 	gl.bindVertexArray(m_vao);
   2890 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   2891 
   2892 	gl.beginTransformFeedback(GL_POINTS);
   2893 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   2894 
   2895 	/* Draw. */
   2896 	gl.drawArrays(GL_POINTS, 0, 1);
   2897 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArrays call failed.");
   2898 
   2899 	/* State reset. */
   2900 	gl.endTransformFeedback();
   2901 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   2902 
   2903 	/* Result query. */
   2904 	glw::GLint* result_ptr = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   2905 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
   2906 
   2907 	glw::GLint result[2] = { result_ptr[0], result_ptr[1] };
   2908 
   2909 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   2910 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   2911 
   2912 	/* Check result and return. */
   2913 	if ((0 == result[0]) || (1 == result[1]))
   2914 	{
   2915 		return true;
   2916 	}
   2917 
   2918 	return false;
   2919 }
   2920 
   2921 /** @brief Clean GL objects. */
   2922 void AttributeBindingTest::Clean()
   2923 {
   2924 	/* Shortcut for GL functionality */
   2925 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   2926 
   2927 	gl.useProgram(0);
   2928 
   2929 	if (m_po)
   2930 	{
   2931 		gl.deleteProgram(m_po);
   2932 
   2933 		m_po = 0;
   2934 	}
   2935 
   2936 	if (m_vao)
   2937 	{
   2938 		gl.deleteVertexArrays(1, &m_vao);
   2939 
   2940 		m_vao = 0;
   2941 	}
   2942 
   2943 	if (m_bo_array)
   2944 	{
   2945 		gl.deleteBuffers(1, &m_bo_array);
   2946 
   2947 		m_bo_array = 0;
   2948 	}
   2949 
   2950 	if (m_bo_xfb)
   2951 	{
   2952 		gl.deleteBuffers(1, &m_bo_xfb);
   2953 
   2954 		m_bo_xfb = 0;
   2955 	}
   2956 
   2957 	while (gl.getError())
   2958 		;
   2959 }
   2960 
   2961 const glw::GLchar AttributeBindingTest::s_vertex_shader[] = "#version 450\n"
   2962 															"\n"
   2963 															"in int a_0;\n"
   2964 															"in int a_1;\n"
   2965 															"out ivec2 result;\n"
   2966 															"\n"
   2967 															"void main()\n"
   2968 															"{\n"
   2969 															"    gl_Position = vec4(1.0);\n"
   2970 															"    result[0] = a_0;\n"
   2971 															"    result[1] = a_1;\n"
   2972 															"}\n";
   2973 
   2974 const glw::GLchar AttributeBindingTest::s_fragment_shader[] = "#version 450\n"
   2975 															  "\n"
   2976 															  "out vec4 color;\n"
   2977 															  "\n"
   2978 															  "void main()\n"
   2979 															  "{\n"
   2980 															  "    color = vec4(1.0);"
   2981 															  "}\n";
   2982 
   2983 /******************************** Vertex Array Attribute Binding Divisor Test Implementation   ********************************/
   2984 
   2985 /** @brief Vertex Array Attribute Binding Divisor Test constructor.
   2986  *
   2987  *  @param [in] context     OpenGL context.
   2988  */
   2989 AttributeBindingDivisorTest::AttributeBindingDivisorTest(deqp::Context& context)
   2990 	: deqp::TestCase(context, "vertex_arrays_attribute_binding_divisor", "Vertex Array Attribute Binding Divisor Test")
   2991 	, m_po(0)
   2992 	, m_vao(0)
   2993 	, m_bo_array(0)
   2994 	, m_bo_xfb(0)
   2995 {
   2996 	/* Intentionally left blank. */
   2997 }
   2998 
   2999 /** @brief Iterate Vertex Array Attribute Binding Divisor Test cases.
   3000  *
   3001  *  @return Iteration result.
   3002  */
   3003 tcu::TestNode::IterateResult AttributeBindingDivisorTest::iterate()
   3004 {
   3005 	/* Shortcut for GL functionality. */
   3006 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3007 
   3008 	/* Get context setup. */
   3009 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
   3010 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
   3011 
   3012 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
   3013 	{
   3014 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
   3015 
   3016 		return STOP;
   3017 	}
   3018 
   3019 	/* Running tests. */
   3020 	bool is_ok	= true;
   3021 	bool is_error = false;
   3022 
   3023 	try
   3024 	{
   3025 		PrepareProgram();
   3026 		PrepareVAO();
   3027 		PrepareXFB();
   3028 
   3029 		{
   3030 			glw::GLint reference[] = { 0, 2 };
   3031 			is_ok				   = SetDivisor(2);
   3032 			Draw(1, 2);
   3033 			is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference,
   3034 							 "Draw of 1 point with 2 instances with 2 divisor has failed.");
   3035 		}
   3036 
   3037 		{
   3038 			glw::GLint reference[] = { 0, 0, 1, 1 };
   3039 			is_ok				   = SetDivisor(1);
   3040 			Draw(2, 2);
   3041 			is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference,
   3042 							 "Draw of 2 points with 2 instances with 1 divisor has failed.");
   3043 		}
   3044 
   3045 		{
   3046 			glw::GLint reference[] = { 0, 1, 2, 3 };
   3047 			is_ok				   = SetDivisor(1);
   3048 			Draw(1, 4);
   3049 			is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference,
   3050 							 "Draw of 1 point with 4 instances with 1 divisor has failed.");
   3051 		}
   3052 
   3053 		{
   3054 			glw::GLint reference[] = { 0, 1, 0, 1 };
   3055 			is_ok				   = SetDivisor(0);
   3056 			Draw(2, 2);
   3057 			is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference,
   3058 							 "Draw of 2 points with 2 instances with 0 divisor has failed.");
   3059 		}
   3060 
   3061 		{
   3062 			glw::GLint reference[] = { 0, 1, 2, 3 };
   3063 			is_ok				   = SetDivisor(0);
   3064 			Draw(4, 1);
   3065 			is_ok = CheckXFB((sizeof(reference) / sizeof(reference[0])), reference,
   3066 							 "Draw of 4 points with 1 instance with 0 divisor has failed.");
   3067 		}
   3068 	}
   3069 	catch (...)
   3070 	{
   3071 		is_ok	= false;
   3072 		is_error = true;
   3073 	}
   3074 
   3075 	/* Cleanup. */
   3076 	Clean();
   3077 
   3078 	/* Errors clean up. */
   3079 	while (gl.getError())
   3080 		;
   3081 
   3082 	/* Result's setup. */
   3083 	if (is_ok)
   3084 	{
   3085 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   3086 	}
   3087 	else
   3088 	{
   3089 		if (is_error)
   3090 		{
   3091 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   3092 		}
   3093 		else
   3094 		{
   3095 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   3096 		}
   3097 	}
   3098 
   3099 	return STOP;
   3100 }
   3101 
   3102 /** @brief Build test's GLSL program.
   3103  *
   3104  *  @note The function may throw if unexpected error has occured.
   3105  */
   3106 void AttributeBindingDivisorTest::PrepareProgram()
   3107 {
   3108 	/* Shortcut for GL functionality */
   3109 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3110 
   3111 	struct Shader
   3112 	{
   3113 		glw::GLchar const* const source;
   3114 		glw::GLenum const		 type;
   3115 		glw::GLuint				 id;
   3116 	} shader[] = { { s_vertex_shader, GL_VERTEX_SHADER, 0 }, { s_fragment_shader, GL_FRAGMENT_SHADER, 0 } };
   3117 
   3118 	glw::GLuint const shader_count = sizeof(shader) / sizeof(shader[0]);
   3119 
   3120 	try
   3121 	{
   3122 		/* Create program. */
   3123 		m_po = gl.createProgram();
   3124 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram call failed.");
   3125 
   3126 		/* Shader compilation. */
   3127 
   3128 		for (glw::GLuint i = 0; i < shader_count; ++i)
   3129 		{
   3130 			if (DE_NULL != shader[i].source)
   3131 			{
   3132 				shader[i].id = gl.createShader(shader[i].type);
   3133 
   3134 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader call failed.");
   3135 
   3136 				gl.attachShader(m_po, shader[i].id);
   3137 
   3138 				GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader call failed.");
   3139 
   3140 				gl.shaderSource(shader[i].id, 1, &(shader[i].source), NULL);
   3141 
   3142 				GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource call failed.");
   3143 
   3144 				gl.compileShader(shader[i].id);
   3145 
   3146 				GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader call failed.");
   3147 
   3148 				glw::GLint status = GL_FALSE;
   3149 
   3150 				gl.getShaderiv(shader[i].id, GL_COMPILE_STATUS, &status);
   3151 				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
   3152 
   3153 				if (GL_FALSE == status)
   3154 				{
   3155 					glw::GLint log_size = 0;
   3156 					gl.getShaderiv(shader[i].id, GL_INFO_LOG_LENGTH, &log_size);
   3157 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv call failed.");
   3158 
   3159 					glw::GLchar* log_text = new glw::GLchar[log_size];
   3160 
   3161 					gl.getShaderInfoLog(shader[i].id, log_size, NULL, &log_text[0]);
   3162 
   3163 					m_context.getTestContext().getLog() << tcu::TestLog::Message << "Shader compilation has failed.\n"
   3164 														<< "Shader type: " << glu::getShaderTypeStr(shader[i].type)
   3165 														<< "\n"
   3166 														<< "Shader compilation error log:\n"
   3167 														<< log_text << "\n"
   3168 														<< "Shader source code:\n"
   3169 														<< shader[i].source << "\n"
   3170 														<< tcu::TestLog::EndMessage;
   3171 
   3172 					delete[] log_text;
   3173 
   3174 					GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderInfoLog call failed.");
   3175 
   3176 					throw 0;
   3177 				}
   3178 			}
   3179 		}
   3180 
   3181 		/* Transform Feedback setup. */
   3182 		static const glw::GLchar* xfb_varying = "result";
   3183 
   3184 		gl.transformFeedbackVaryings(m_po, 1, &xfb_varying, GL_INTERLEAVED_ATTRIBS);
   3185 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
   3186 
   3187 		/* Link. */
   3188 		gl.linkProgram(m_po);
   3189 
   3190 		GLU_EXPECT_NO_ERROR(gl.getError(), "glTransformFeedbackVaryings call failed.");
   3191 
   3192 		glw::GLint status = GL_FALSE;
   3193 
   3194 		gl.getProgramiv(m_po, GL_LINK_STATUS, &status);
   3195 
   3196 		if (GL_TRUE == status)
   3197 		{
   3198 			for (glw::GLuint i = 0; i < shader_count; ++i)
   3199 			{
   3200 				if (shader[i].id)
   3201 				{
   3202 					gl.detachShader(m_po, shader[i].id);
   3203 
   3204 					GLU_EXPECT_NO_ERROR(gl.getError(), "glDetachShader call failed.");
   3205 				}
   3206 			}
   3207 		}
   3208 		else
   3209 		{
   3210 			glw::GLint log_size = 0;
   3211 
   3212 			gl.getProgramiv(m_po, GL_INFO_LOG_LENGTH, &log_size);
   3213 
   3214 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv call failed.");
   3215 
   3216 			glw::GLchar* log_text = new glw::GLchar[log_size];
   3217 
   3218 			gl.getProgramInfoLog(m_po, log_size, NULL, &log_text[0]);
   3219 
   3220 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Program linkage has failed due to:\n"
   3221 												<< log_text << "\n"
   3222 												<< tcu::TestLog::EndMessage;
   3223 
   3224 			delete[] log_text;
   3225 
   3226 			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramInfoLog call failed.");
   3227 
   3228 			throw 0;
   3229 		}
   3230 	}
   3231 	catch (...)
   3232 	{
   3233 		if (m_po)
   3234 		{
   3235 			gl.deleteProgram(m_po);
   3236 
   3237 			m_po = 0;
   3238 		}
   3239 	}
   3240 
   3241 	for (glw::GLuint i = 0; i < shader_count; ++i)
   3242 	{
   3243 		if (0 != shader[i].id)
   3244 		{
   3245 			gl.deleteShader(shader[i].id);
   3246 
   3247 			shader[i].id = 0;
   3248 		}
   3249 	}
   3250 
   3251 	if (m_po)
   3252 	{
   3253 		gl.useProgram(m_po);
   3254 		GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram call failed.");
   3255 	}
   3256 
   3257 	if (0 == m_po)
   3258 	{
   3259 		throw 0;
   3260 	}
   3261 }
   3262 
   3263 /** @brief Prepare vertex array object for the test.
   3264  */
   3265 void AttributeBindingDivisorTest::PrepareVAO()
   3266 {
   3267 	/* Shortcut for GL functionality */
   3268 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3269 
   3270 	/* VAO creation. */
   3271 	gl.genVertexArrays(1, &m_vao);
   3272 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays call failed.");
   3273 
   3274 	gl.bindVertexArray(m_vao);
   3275 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   3276 
   3277 	/* Array buffer 0 creation. */
   3278 	glw::GLint array_data[4] = { 0, 1, 2, 3 };
   3279 
   3280 	gl.genBuffers(1, &m_bo_array);
   3281 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   3282 
   3283 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo_array);
   3284 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   3285 
   3286 	gl.bufferData(GL_ARRAY_BUFFER, sizeof(array_data), array_data, GL_STATIC_DRAW);
   3287 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData call failed.");
   3288 
   3289 	gl.vertexAttribBinding(gl.getAttribLocation(m_po, "a"), 0);
   3290 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed.");
   3291 
   3292 	gl.vertexAttribIFormat(gl.getAttribLocation(m_po, "a"), 1, GL_INT, 0);
   3293 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIFormat call failed.");
   3294 
   3295 	gl.bindVertexBuffer(0, m_bo_array, 0, sizeof(glw::GLint));
   3296 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexBuffer call failed.");
   3297 
   3298 	gl.enableVertexAttribArray(gl.getAttribLocation(m_po, "a"));
   3299 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   3300 }
   3301 
   3302 /** @brief Prepare buffer object for test GLSL program transform feedback results.
   3303  */
   3304 void AttributeBindingDivisorTest::PrepareXFB()
   3305 {
   3306 	/* Shortcut for GL functionality */
   3307 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3308 
   3309 	/* Buffer creation. */
   3310 	gl.genBuffers(1, &m_bo_xfb);
   3311 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers call failed.");
   3312 
   3313 	gl.bindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_bo_xfb);
   3314 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   3315 
   3316 	/* Preparing storage. */
   3317 	gl.bufferStorage(GL_TRANSFORM_FEEDBACK_BUFFER, 4 * sizeof(glw::GLint), NULL, GL_MAP_READ_BIT);
   3318 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferStorage call failed.");
   3319 
   3320 	gl.bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_bo_xfb);
   3321 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBufferBase call failed.");
   3322 }
   3323 
   3324 /** @brief Draw number of points and number of instances with XFB environment.
   3325  *
   3326  *  @param [in] number_of_points        Number of points to be drawn.
   3327  *  @param [in] number_of_instances     Number of instances to be drawn.
   3328  */
   3329 void AttributeBindingDivisorTest::Draw(glw::GLuint number_of_points, glw::GLuint number_of_instances)
   3330 {
   3331 	/* Shortcut for GL functionality */
   3332 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3333 
   3334 	/* Setup state. */
   3335 	gl.beginTransformFeedback(GL_POINTS);
   3336 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBeginTransformFeedback call failed.");
   3337 
   3338 	/* Draw. */
   3339 	gl.drawArraysInstanced(GL_POINTS, 0, number_of_points, number_of_instances);
   3340 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArraysInstanced call failed.");
   3341 
   3342 	/* State reset. */
   3343 	gl.endTransformFeedback();
   3344 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEndTransformFeedback call failed.");
   3345 }
   3346 
   3347 /** @brief Call VertexArrayBindingDivisor on m_vao object and check errors.
   3348  *
   3349  *  @param [in] divisor        Divisor to be passed.
   3350  *
   3351  *  @return True if VertexArrayBindingDivisor doe not generate any error, false otherwise.
   3352  */
   3353 bool AttributeBindingDivisorTest::SetDivisor(glw::GLuint divisor)
   3354 {
   3355 	/* Shortcut for GL functionality */
   3356 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3357 
   3358 	/* Setup. */
   3359 	gl.vertexArrayBindingDivisor(m_vao, 0, divisor);
   3360 
   3361 	/* Checking for errors (this is tested function so it fail the test if there is error). */
   3362 	if (glw::GLenum error = gl.getError())
   3363 	{
   3364 		m_context.getTestContext().getLog()
   3365 			<< tcu::TestLog::Message << "VertexArrayBindingDivisor unexpectedl generated " << glu::getErrorStr(error)
   3366 			<< " error when called with divisor" << divisor << ". " << tcu::TestLog::EndMessage;
   3367 
   3368 		return false;
   3369 	}
   3370 
   3371 	return true;
   3372 }
   3373 
   3374 /** @brief Check transform feedback results and log.
   3375  *
   3376  *  @param [in] count           Number of results to be checked.
   3377  *  @param [in] expected        Expected results.
   3378  *  @param [in] log_message     Message to be logged if expected values are not equal to queried.
   3379  *
   3380  *  @return True if expected values are equal to queried, false otherwise.
   3381  */
   3382 bool AttributeBindingDivisorTest::CheckXFB(const glw::GLuint count, const glw::GLint expected[],
   3383 										   const glw::GLchar* log_message)
   3384 {
   3385 	/* Shortcut for GL functionality */
   3386 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3387 
   3388 	/* Result setup */
   3389 	bool is_ok = true;
   3390 
   3391 	/* Result query. */
   3392 	glw::GLint* result = (glw::GLint*)gl.mapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, GL_READ_ONLY);
   3393 	GLU_EXPECT_NO_ERROR(gl.getError(), "glMapBuffer call failed.");
   3394 
   3395 	/* Check result and return. */
   3396 	for (glw::GLuint i = 0; i < count; ++i)
   3397 	{
   3398 		if (expected[i] != result[i])
   3399 		{
   3400 			std::string expected_str = "[";
   3401 			std::string result_str   = "[";
   3402 
   3403 			for (glw::GLuint j = 0; j < count; ++j)
   3404 			{
   3405 				expected_str.append(Utilities::itoa((glw::GLuint)expected[j]));
   3406 				result_str.append(Utilities::itoa((glw::GLuint)result[j]));
   3407 
   3408 				if (j < count - 1)
   3409 				{
   3410 					expected_str.append(", ");
   3411 					result_str.append(", ");
   3412 				}
   3413 				else
   3414 				{
   3415 					expected_str.append("]");
   3416 					result_str.append("]");
   3417 				}
   3418 			}
   3419 
   3420 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "Result is " << result_str << ", but "
   3421 												<< expected_str << " was expected. " << log_message
   3422 												<< tcu::TestLog::EndMessage;
   3423 
   3424 			is_ok = false;
   3425 			break;
   3426 		}
   3427 	}
   3428 
   3429 	/* Unmaping GL buffer. */
   3430 	gl.unmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
   3431 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUnmapBuffer call failed.");
   3432 
   3433 	return is_ok;
   3434 }
   3435 
   3436 /** @brief Clean GL objects. */
   3437 void AttributeBindingDivisorTest::Clean()
   3438 {
   3439 	/* Shortcut for GL functionality */
   3440 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3441 
   3442 	gl.useProgram(0);
   3443 
   3444 	if (m_po)
   3445 	{
   3446 		gl.deleteProgram(m_po);
   3447 
   3448 		m_po = 0;
   3449 	}
   3450 
   3451 	if (m_vao)
   3452 	{
   3453 		gl.deleteVertexArrays(1, &m_vao);
   3454 
   3455 		m_vao = 0;
   3456 	}
   3457 
   3458 	if (m_bo_array)
   3459 	{
   3460 		gl.deleteBuffers(1, &m_bo_array);
   3461 
   3462 		m_bo_array = 0;
   3463 	}
   3464 
   3465 	if (m_bo_xfb)
   3466 	{
   3467 		gl.deleteBuffers(1, &m_bo_xfb);
   3468 
   3469 		m_bo_xfb = 0;
   3470 	}
   3471 
   3472 	while (gl.getError())
   3473 		;
   3474 }
   3475 
   3476 const glw::GLchar AttributeBindingDivisorTest::s_vertex_shader[] = "#version 450\n"
   3477 																   "\n"
   3478 																   "in  int a;\n"
   3479 																   "out int result;\n"
   3480 																   "\n"
   3481 																   "void main()\n"
   3482 																   "{\n"
   3483 																   "    gl_Position = vec4(1.0);\n"
   3484 																   "    result = a;"
   3485 																   "}\n";
   3486 
   3487 const glw::GLchar AttributeBindingDivisorTest::s_fragment_shader[] = "#version 450\n"
   3488 																	 "\n"
   3489 																	 "out vec4 color;\n"
   3490 																	 "\n"
   3491 																	 "void main()\n"
   3492 																	 "{\n"
   3493 																	 "    color = vec4(1.0);"
   3494 																	 "}\n";
   3495 
   3496 /******************************** Get Vertex Array Test Implementation   ********************************/
   3497 
   3498 /** @brief Get Vertex Array Test constructor.
   3499  *
   3500  *  @param [in] context     OpenGL context.
   3501  */
   3502 GetVertexArrayTest::GetVertexArrayTest(deqp::Context& context)
   3503 	: deqp::TestCase(context, "vertex_arrays_get_vertex_array", "Get Vertex Array Test")
   3504 {
   3505 	/* Intentionally left blank. */
   3506 }
   3507 
   3508 /** @brief Iterate Vertex Array Attribute Binding Divisor Test cases.
   3509  *
   3510  *  @return Iteration result.
   3511  */
   3512 tcu::TestNode::IterateResult GetVertexArrayTest::iterate()
   3513 {
   3514 	/* Shortcut for GL functionality. */
   3515 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3516 
   3517 	/* Get context setup. */
   3518 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
   3519 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
   3520 
   3521 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
   3522 	{
   3523 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
   3524 
   3525 		return STOP;
   3526 	}
   3527 
   3528 	/* Running tests. */
   3529 	bool is_ok	= true;
   3530 	bool is_error = false;
   3531 
   3532 	/* Test objects. */
   3533 	glw::GLuint vao = 0;
   3534 	glw::GLuint bo  = 0;
   3535 
   3536 	try
   3537 	{
   3538 		gl.genVertexArrays(1, &vao);
   3539 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
   3540 
   3541 		gl.bindVertexArray(vao);
   3542 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   3543 
   3544 		gl.genBuffers(1, &bo);
   3545 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers call failed.");
   3546 
   3547 		gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, bo);
   3548 		GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   3549 
   3550 		glw::GLint result = 0;
   3551 		gl.getVertexArrayiv(vao, GL_ELEMENT_ARRAY_BUFFER_BINDING, &result);
   3552 
   3553 		if (glw::GLenum error = gl.getError())
   3554 		{
   3555 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetVertexArrayiv unexpectedly generated "
   3556 												<< glu::getErrorStr(error) << "error. Test fails."
   3557 												<< tcu::TestLog::EndMessage;
   3558 
   3559 			is_ok = false;
   3560 		}
   3561 
   3562 		if ((glw::GLuint)result != bo)
   3563 		{
   3564 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetVertexArrayiv was expected to return "
   3565 												<< bo << ", but " << result << " was observed. Test fails."
   3566 												<< tcu::TestLog::EndMessage;
   3567 
   3568 			is_ok = false;
   3569 		}
   3570 	}
   3571 	catch (...)
   3572 	{
   3573 		is_ok	= false;
   3574 		is_error = true;
   3575 	}
   3576 
   3577 	/* Cleanup. */
   3578 	if (vao)
   3579 	{
   3580 		gl.deleteVertexArrays(1, &vao);
   3581 	}
   3582 
   3583 	if (bo)
   3584 	{
   3585 		gl.deleteBuffers(1, &bo);
   3586 	}
   3587 
   3588 	/* Errors clean up. */
   3589 	while (gl.getError())
   3590 		;
   3591 
   3592 	/* Result's setup. */
   3593 	if (is_ok)
   3594 	{
   3595 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   3596 	}
   3597 	else
   3598 	{
   3599 		if (is_error)
   3600 		{
   3601 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   3602 		}
   3603 		else
   3604 		{
   3605 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   3606 		}
   3607 	}
   3608 
   3609 	return STOP;
   3610 }
   3611 
   3612 /******************************** Get Vertex Array Test Indexed Implementation   ********************************/
   3613 
   3614 /** @brief Get Vertex Array Indexed Test constructor.
   3615  *
   3616  *  @param [in] context     OpenGL context.
   3617  */
   3618 GetVertexArrayIndexedTest::GetVertexArrayIndexedTest(deqp::Context& context)
   3619 	: deqp::TestCase(context, "vertex_arrays_get_vertex_array_indexed", "Get Vertex Array Indexed Test"), m_vao(0)
   3620 {
   3621 	m_bo[0] = 0;
   3622 	m_bo[1] = 0;
   3623 	m_bo[2] = 0;
   3624 	m_bo[3] = 0;
   3625 }
   3626 
   3627 /** @brief Iterate Vertex Array Attribute Binding Divisor Test cases.
   3628  *
   3629  *  @return Iteration result.
   3630  */
   3631 tcu::TestNode::IterateResult GetVertexArrayIndexedTest::iterate()
   3632 {
   3633 	/* Shortcut for GL functionality. */
   3634 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3635 
   3636 	/* Get context setup. */
   3637 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
   3638 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
   3639 
   3640 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
   3641 	{
   3642 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
   3643 
   3644 		return STOP;
   3645 	}
   3646 
   3647 	/* Running tests. */
   3648 	bool is_ok	= true;
   3649 	bool is_error = false;
   3650 
   3651 	try
   3652 	{
   3653 		PrepareVAO();
   3654 
   3655 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 0, GL_TRUE);
   3656 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 1, GL_TRUE);
   3657 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 2, GL_TRUE);
   3658 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 3, GL_TRUE);
   3659 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_ENABLED, 5, GL_FALSE);
   3660 
   3661 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_STRIDE, 0, 0);
   3662 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_STRIDE, 1, 2);
   3663 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_STRIDE, 2, 0);
   3664 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_STRIDE, 3, 8);
   3665 
   3666 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_TYPE, 0, GL_BYTE);
   3667 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_TYPE, 1, GL_SHORT);
   3668 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_TYPE, 2, GL_FLOAT);
   3669 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_TYPE, 3, GL_UNSIGNED_INT_2_10_10_10_REV);
   3670 
   3671 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 0, GL_TRUE);
   3672 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 1, GL_FALSE);
   3673 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 2, GL_FALSE);
   3674 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 3, GL_FALSE);
   3675 
   3676 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_INTEGER, 0, GL_FALSE);
   3677 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_INTEGER, 1, GL_TRUE);
   3678 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_INTEGER, 2, GL_FALSE);
   3679 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_INTEGER, 3, GL_FALSE);
   3680 
   3681 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 0, 3);
   3682 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 1, 2);
   3683 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 2, 1);
   3684 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 3, 0);
   3685 
   3686 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_LONG, 0, GL_FALSE);
   3687 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_LONG, 1, GL_FALSE);
   3688 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_LONG, 2, GL_FALSE);
   3689 		is_ok &= Check(GL_VERTEX_ATTRIB_ARRAY_LONG, 3, GL_FALSE);
   3690 
   3691 		is_ok &= Check(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 0, 0);
   3692 		is_ok &= Check(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 1, 0);
   3693 		is_ok &= Check(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 2, 4);
   3694 		is_ok &= Check(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, 3, 0);
   3695 
   3696 		is_ok &= Check64(GL_VERTEX_BINDING_OFFSET, 0, 0);
   3697 		is_ok &= Check64(GL_VERTEX_BINDING_OFFSET, 1, 2);
   3698 		is_ok &= Check64(GL_VERTEX_BINDING_OFFSET, 2, 8);
   3699 		is_ok &= Check64(GL_VERTEX_BINDING_OFFSET, 3, 4);
   3700 	}
   3701 	catch (...)
   3702 	{
   3703 		is_ok	= false;
   3704 		is_error = true;
   3705 	}
   3706 
   3707 	/* Cleanup. */
   3708 	if (m_vao)
   3709 	{
   3710 		gl.deleteVertexArrays(1, &m_vao);
   3711 
   3712 		m_vao = 0;
   3713 	}
   3714 
   3715 	if (m_bo[0] || m_bo[1] || m_bo[2] || m_bo[3])
   3716 	{
   3717 		gl.deleteBuffers(4, m_bo);
   3718 
   3719 		m_bo[0] = 0;
   3720 		m_bo[1] = 0;
   3721 		m_bo[2] = 0;
   3722 		m_bo[3] = 0;
   3723 	}
   3724 
   3725 	/* Errors clean up. */
   3726 	while (gl.getError())
   3727 		;
   3728 
   3729 	/* Result's setup. */
   3730 	if (is_ok)
   3731 	{
   3732 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   3733 	}
   3734 	else
   3735 	{
   3736 		if (is_error)
   3737 		{
   3738 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   3739 		}
   3740 		else
   3741 		{
   3742 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   3743 		}
   3744 	}
   3745 
   3746 	return STOP;
   3747 }
   3748 
   3749 /** @brief Prepare vertex array object for the test.
   3750  */
   3751 void GetVertexArrayIndexedTest::PrepareVAO()
   3752 {
   3753 	/* Shortcut for GL functionality. */
   3754 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3755 
   3756 	gl.genVertexArrays(1, &m_vao);
   3757 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
   3758 
   3759 	gl.bindVertexArray(m_vao);
   3760 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray call failed.");
   3761 
   3762 	gl.genBuffers(4, m_bo);
   3763 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers call failed.");
   3764 
   3765 	/* Attribute 0. */
   3766 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo[0]);
   3767 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   3768 
   3769 	gl.vertexAttribPointer(0, 1, GL_BYTE, GL_TRUE, 0, NULL);
   3770 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
   3771 
   3772 	gl.enableVertexAttribArray(0);
   3773 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   3774 
   3775 	gl.vertexAttribDivisor(0, 3);
   3776 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribDivisor call failed.");
   3777 
   3778 	/* Attribute 1. */
   3779 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo[1]);
   3780 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   3781 
   3782 	gl.vertexAttribIPointer(1, 2, GL_SHORT, 2, ((glw::GLchar*)NULL + 2));
   3783 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
   3784 
   3785 	gl.enableVertexAttribArray(1);
   3786 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   3787 
   3788 	gl.vertexAttribDivisor(1, 2);
   3789 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribDivisor call failed.");
   3790 
   3791 	/* Attribute 2. */
   3792 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo[2]);
   3793 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   3794 
   3795 	gl.vertexAttribBinding(2, 2);
   3796 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribBinding call failed.");
   3797 
   3798 	gl.vertexAttribFormat(2, 3, GL_FLOAT, GL_FALSE, 4);
   3799 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribIFormat call failed.");
   3800 
   3801 	gl.bindVertexBuffer(2, m_bo[2], 8, 0);
   3802 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexBuffer call failed.");
   3803 
   3804 	gl.enableVertexAttribArray(2);
   3805 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   3806 
   3807 	gl.vertexAttribDivisor(2, 1);
   3808 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribDivisor call failed.");
   3809 
   3810 	/* Attribute 3. */
   3811 	gl.bindBuffer(GL_ARRAY_BUFFER, m_bo[3]);
   3812 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer call failed.");
   3813 
   3814 	gl.vertexAttribPointer(3, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 8, ((glw::GLchar*)NULL + 4));
   3815 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer call failed.");
   3816 
   3817 	gl.enableVertexAttribArray(3);
   3818 	GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray call failed.");
   3819 
   3820 	gl.vertexAttribDivisor(3, 0);
   3821 	GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribDivisor call failed.");
   3822 }
   3823 
   3824 /** @brief Compare value queried using GetVertexArrayIndexediv with expected value and log.
   3825  *
   3826  *  @param [in] pname        Parameter to be queried.
   3827  *  @param [in] index        Index to be queried.
   3828  *  @param [in] expected     Expected error.
   3829  *
   3830  *  @return True if value is equal to expected, false otherwise.
   3831  */
   3832 bool GetVertexArrayIndexedTest::Check(const glw::GLenum pname, const glw::GLuint index, const glw::GLint expected)
   3833 {
   3834 	/* Shortcut for GL functionality. */
   3835 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3836 
   3837 	glw::GLint result = 0;
   3838 
   3839 	gl.getVertexArrayIndexediv(m_vao, index, pname, &result);
   3840 
   3841 	if (glw::GLenum error = gl.getError())
   3842 	{
   3843 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetVertexArrayIndexediv called with index "
   3844 											<< index << ", with pname" << glu::getVertexAttribParameterNameStr(pname)
   3845 											<< " unexpectedly generated " << glu::getErrorStr(error)
   3846 											<< "error. Test fails." << tcu::TestLog::EndMessage;
   3847 
   3848 		return false;
   3849 	}
   3850 
   3851 	if (result != expected)
   3852 	{
   3853 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetVertexArrayIndexediv called with index "
   3854 											<< index << " and with pname" << glu::getVertexAttribParameterNameStr(pname)
   3855 											<< " returned " << result << ", but " << expected
   3856 											<< " was expected. Test fails." << tcu::TestLog::EndMessage;
   3857 
   3858 		return false;
   3859 	}
   3860 
   3861 	return true;
   3862 }
   3863 
   3864 /** @brief Compare value queried using GetVertexArrayIndexed64iv with expected value and log.
   3865  *
   3866  *  @param [in] pname        Parameter to be queried.
   3867  *  @param [in] index        Index to be queried.
   3868  *  @param [in] expected     Expected error.
   3869  *
   3870  *  @return True if value is equal to expected, false otherwise.
   3871  */
   3872 bool GetVertexArrayIndexedTest::Check64(const glw::GLenum pname, const glw::GLuint index, const glw::GLint64 expected)
   3873 {
   3874 	/* Shortcut for GL functionality. */
   3875 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3876 
   3877 	glw::GLint64 result = 0;
   3878 
   3879 	gl.getVertexArrayIndexed64iv(m_vao, index, pname, &result);
   3880 
   3881 	if (glw::GLenum error = gl.getError())
   3882 	{
   3883 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetVertexArrayIndexed64iv called with index "
   3884 											<< index << ", with pname" << glu::getVertexAttribParameterNameStr(pname)
   3885 											<< " unexpectedly generated " << glu::getErrorStr(error)
   3886 											<< "error. Test fails." << tcu::TestLog::EndMessage;
   3887 
   3888 		return false;
   3889 	}
   3890 
   3891 	if (result != expected)
   3892 	{
   3893 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "GetVertexArrayIndexed64iv called with index "
   3894 											<< index << " and with pname" << glu::getVertexAttribParameterNameStr(pname)
   3895 											<< " returned " << result << ", but " << expected
   3896 											<< " was expected. Test fails." << tcu::TestLog::EndMessage;
   3897 
   3898 		return false;
   3899 	}
   3900 
   3901 	return true;
   3902 }
   3903 
   3904 /******************************** Defaults Test Implementation   ********************************/
   3905 
   3906 /** @brief Defaults Test constructor.
   3907  *
   3908  *  @param [in] context     OpenGL context.
   3909  */
   3910 DefaultsTest::DefaultsTest(deqp::Context& context)
   3911 	: deqp::TestCase(context, "vertex_arrays_defaults", "Defaults Test"), m_vao(0)
   3912 {
   3913 }
   3914 
   3915 /** @brief Iterate Defaults Test cases.
   3916  *
   3917  *  @return Iteration result.
   3918  */
   3919 tcu::TestNode::IterateResult DefaultsTest::iterate()
   3920 {
   3921 	/* Shortcut for GL functionality. */
   3922 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   3923 
   3924 	/* Get context setup. */
   3925 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
   3926 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
   3927 
   3928 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
   3929 	{
   3930 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
   3931 
   3932 		return STOP;
   3933 	}
   3934 
   3935 	/* Running tests. */
   3936 	bool is_ok	= true;
   3937 	bool is_error = false;
   3938 
   3939 	/* Test objects. */
   3940 	glw::GLint max_attributes = 8;
   3941 
   3942 	try
   3943 	{
   3944 		/* Query limits. */
   3945 		gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_attributes);
   3946 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   3947 
   3948 		/* Prepare default Vertex Array Object. */
   3949 		PrepareVAO();
   3950 
   3951 		/* Check default values per attribute index. */
   3952 		for (glw::GLint i = 0; i < max_attributes; ++i)
   3953 		{
   3954 			is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_ENABLED, i, GL_FALSE);
   3955 			is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_SIZE, i, 4);
   3956 			is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_STRIDE, i, 0);
   3957 			is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_TYPE, i, GL_FLOAT);
   3958 			is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, i, GL_FALSE);
   3959 			is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_INTEGER, i, GL_FALSE);
   3960 			is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_DIVISOR, i, 0);
   3961 			is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_ARRAY_LONG, i, GL_FALSE);
   3962 			is_ok &= CheckIndexed(GL_VERTEX_ATTRIB_RELATIVE_OFFSET, i, 0);
   3963 			is_ok &= CheckIndexed64(GL_VERTEX_BINDING_OFFSET, i, 0);
   3964 		}
   3965 
   3966 		/* Check default values per vertex array object. */
   3967 		is_ok &= Check(GL_ELEMENT_ARRAY_BUFFER_BINDING, 0);
   3968 	}
   3969 	catch (...)
   3970 	{
   3971 		is_ok	= false;
   3972 		is_error = true;
   3973 	}
   3974 
   3975 	/* Cleanup. */
   3976 	if (m_vao)
   3977 	{
   3978 		gl.deleteVertexArrays(1, &m_vao);
   3979 
   3980 		m_vao = 0;
   3981 	}
   3982 
   3983 	/* Errors clean up. */
   3984 	while (gl.getError())
   3985 		;
   3986 
   3987 	/* Result's setup. */
   3988 	if (is_ok)
   3989 	{
   3990 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   3991 	}
   3992 	else
   3993 	{
   3994 		if (is_error)
   3995 		{
   3996 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   3997 		}
   3998 		else
   3999 		{
   4000 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4001 		}
   4002 	}
   4003 
   4004 	return STOP;
   4005 }
   4006 
   4007 /** @brief Prepare vertex array object for the test.
   4008  */
   4009 void DefaultsTest::PrepareVAO()
   4010 {
   4011 	/* Shortcut for GL functionality. */
   4012 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4013 
   4014 	gl.createVertexArrays(1, &m_vao);
   4015 	GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
   4016 }
   4017 
   4018 /** @brief Compare value queried using GetVertexArrayiv with expected value and log.
   4019  *
   4020  *  @param [in] pname        Parameter to be queried.
   4021  *  @param [in] expected     Expected error.
   4022  *
   4023  *  @return True if value is equal to expected, false otherwise.
   4024  */
   4025 bool DefaultsTest::Check(const glw::GLenum pname, const glw::GLint expected)
   4026 {
   4027 	/* Shortcut for GL functionality. */
   4028 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4029 
   4030 	glw::GLint result = 0;
   4031 
   4032 	gl.getVertexArrayiv(m_vao, pname, &result);
   4033 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetVertexArrayiv call failed.");
   4034 
   4035 	if (result != expected)
   4036 	{
   4037 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Default Vertex Array Object has parameter "
   4038 											<< glu::getVertexAttribParameterNameStr(pname) << " equal to " << result
   4039 											<< ", but " << expected << " was expected. Test fails."
   4040 											<< tcu::TestLog::EndMessage;
   4041 
   4042 		return false;
   4043 	}
   4044 
   4045 	return true;
   4046 }
   4047 
   4048 /** @brief Compare value queried using GetVertexArrayIndexediv with expected value and log.
   4049  *
   4050  *  @param [in] pname        Parameter to be queried.
   4051  *  @param [in] index        Index to be queried.
   4052  *  @param [in] expected     Expected error.
   4053  *
   4054  *  @return True if value is equal to expected, false otherwise.
   4055  */
   4056 bool DefaultsTest::CheckIndexed(const glw::GLenum pname, const glw::GLuint index, const glw::GLint expected)
   4057 {
   4058 	/* Shortcut for GL functionality. */
   4059 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4060 
   4061 	glw::GLint result = 0;
   4062 
   4063 	gl.getVertexArrayIndexediv(m_vao, index, pname, &result);
   4064 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetVertexArrayIndexediv call failed.");
   4065 
   4066 	if (result != expected)
   4067 	{
   4068 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Default Vertex Array Object at index " << index
   4069 											<< " has parameter " << glu::getVertexAttribParameterNameStr(pname)
   4070 											<< " equal to " << result << ", but " << expected
   4071 											<< " was expected. Test fails." << tcu::TestLog::EndMessage;
   4072 
   4073 		return false;
   4074 	}
   4075 
   4076 	return true;
   4077 }
   4078 
   4079 /** @brief Compare value queried using GetVertexArrayIndexed64iv with expected value and log.
   4080  *
   4081  *  @param [in] pname        Parameter to be queried.
   4082  *  @param [in] index        Index to be queried.
   4083  *  @param [in] expected     Expected error.
   4084  *
   4085  *  @return True if value is equal to expected, false otherwise.
   4086  */
   4087 bool DefaultsTest::CheckIndexed64(const glw::GLenum pname, const glw::GLuint index, const glw::GLint64 expected)
   4088 {
   4089 	/* Shortcut for GL functionality. */
   4090 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4091 
   4092 	glw::GLint64 result = 0;
   4093 
   4094 	gl.getVertexArrayIndexed64iv(m_vao, index, pname, &result);
   4095 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetVertexArrayIndexed64iv call failed.");
   4096 
   4097 	if (result != expected)
   4098 	{
   4099 		m_context.getTestContext().getLog() << tcu::TestLog::Message << "Default Vertex Array Object at index " << index
   4100 											<< " has parameter " << glu::getVertexAttribParameterNameStr(pname)
   4101 											<< " equal to " << result << ", but " << expected
   4102 											<< " was expected. Test fails." << tcu::TestLog::EndMessage;
   4103 
   4104 		return false;
   4105 	}
   4106 
   4107 	return true;
   4108 }
   4109 
   4110 /******************************** Creation Error Test Implementation   ********************************/
   4111 
   4112 /** @brief Creation Error Test constructor.
   4113  *
   4114  *  @param [in] context     OpenGL context.
   4115  */
   4116 CreationErrorTest::CreationErrorTest(deqp::Context& context)
   4117 	: deqp::TestCase(context, "vertex_arrays_creation_error", "Creation Error Test")
   4118 {
   4119 }
   4120 
   4121 /** @brief Iterate Creation Error Test cases.
   4122  *
   4123  *  @return Iteration result.
   4124  */
   4125 tcu::TestNode::IterateResult CreationErrorTest::iterate()
   4126 {
   4127 	/* Shortcut for GL functionality. */
   4128 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4129 
   4130 	/* Get context setup. */
   4131 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
   4132 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
   4133 
   4134 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
   4135 	{
   4136 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
   4137 
   4138 		return STOP;
   4139 	}
   4140 
   4141 	/* Running tests. */
   4142 	bool is_ok	= true;
   4143 	bool is_error = false;
   4144 
   4145 	try
   4146 	{
   4147 		glw::GLuint negative_vao = 0;
   4148 
   4149 		gl.createVertexArrays(-1, &negative_vao);
   4150 
   4151 		is_ok = CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated if n is negative.");
   4152 	}
   4153 	catch (...)
   4154 	{
   4155 		is_ok	= false;
   4156 		is_error = true;
   4157 	}
   4158 
   4159 	/* Errors clean up. */
   4160 	while (gl.getError())
   4161 		;
   4162 
   4163 	/* Result's setup. */
   4164 	if (is_ok)
   4165 	{
   4166 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4167 	}
   4168 	else
   4169 	{
   4170 		if (is_error)
   4171 		{
   4172 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   4173 		}
   4174 		else
   4175 		{
   4176 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4177 		}
   4178 	}
   4179 
   4180 	return STOP;
   4181 }
   4182 
   4183 /** @brief Compare error returned by GL with expected value and log.
   4184  *
   4185  *  @param [in] expected        Expected error.
   4186  *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
   4187  *
   4188  *  @return True if GL error is equal to expected, false otherwise.
   4189  */
   4190 bool CreationErrorTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message)
   4191 {
   4192 	/* Shortcut for GL functionality. */
   4193 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4194 
   4195 	glw::GLenum error = 0;
   4196 
   4197 	if (expected != (error = gl.getError()))
   4198 	{
   4199 		m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
   4200 											<< "was observed instead." << tcu::TestLog::EndMessage;
   4201 
   4202 		return false;
   4203 	}
   4204 
   4205 	return true;
   4206 }
   4207 
   4208 /******************************** Enable Disable Attribute Errors Test Implementation   ********************************/
   4209 
   4210 /** @brief Enable Disable Attribute Errors Test constructor.
   4211  *
   4212  *  @param [in] context     OpenGL context.
   4213  */
   4214 EnableDisableAttributeErrorsTest::EnableDisableAttributeErrorsTest(deqp::Context& context)
   4215 	: deqp::TestCase(context, "vertex_arrays_enable_disable_attribute_errors", "Enable Disable Attribute Errors Test")
   4216 {
   4217 }
   4218 
   4219 /** @brief Enable Disable Attribute Errors Test cases.
   4220  *
   4221  *  @return Iteration result.
   4222  */
   4223 tcu::TestNode::IterateResult EnableDisableAttributeErrorsTest::iterate()
   4224 {
   4225 	/* Shortcut for GL functionality. */
   4226 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4227 
   4228 	/* Get context setup. */
   4229 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
   4230 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
   4231 
   4232 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
   4233 	{
   4234 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
   4235 
   4236 		return STOP;
   4237 	}
   4238 
   4239 	/* Running tests. */
   4240 	bool is_ok	= true;
   4241 	bool is_error = false;
   4242 
   4243 	/* Test objects. */
   4244 	glw::GLint max_attributes = 8;
   4245 
   4246 	/* Tested VAOs. */
   4247 	glw::GLuint vao		  = 0;
   4248 	glw::GLuint not_a_vao = 0;
   4249 	try
   4250 	{
   4251 		/* Query limits. */
   4252 		gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_attributes);
   4253 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   4254 
   4255 		/* Prepare valid VAO. */
   4256 		gl.createVertexArrays(1, &vao);
   4257 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
   4258 
   4259 		/* Prepare invalid VAO. */
   4260 		while (gl.isVertexArray(++not_a_vao))
   4261 			;
   4262 
   4263 		/* Test not a VAO. */
   4264 		gl.enableVertexArrayAttrib(0, not_a_vao);
   4265 
   4266 		is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by EnableVertexArrayAttrib if "
   4267 												  "vaobj is not the name of an existing vertex array object.");
   4268 
   4269 		gl.disableVertexArrayAttrib(0, not_a_vao);
   4270 
   4271 		is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by DisableVertexArrayAttrib if "
   4272 												  "vaobj is not the name of an existing vertex array object.");
   4273 
   4274 		/* Test to big attribute index. */
   4275 		gl.enableVertexArrayAttrib(max_attributes, vao);
   4276 
   4277 		is_ok &= CheckError(
   4278 			GL_INVALID_OPERATION,
   4279 			"INVALID_VALUE was not generated by EnableVertexArrayAttrib if index is equal to MAX_VERTEX_ATTRIBS.");
   4280 
   4281 		gl.disableVertexArrayAttrib(max_attributes, vao);
   4282 
   4283 		is_ok &= CheckError(
   4284 			GL_INVALID_OPERATION,
   4285 			"INVALID_VALUE was not generated by DisableVertexArrayAttrib if index is equal to MAX_VERTEX_ATTRIBS.");
   4286 
   4287 		gl.enableVertexArrayAttrib(max_attributes + 1, vao);
   4288 
   4289 		is_ok &= CheckError(
   4290 			GL_INVALID_OPERATION,
   4291 			"INVALID_VALUE was not generated by EnableVertexArrayAttrib if index is greater than MAX_VERTEX_ATTRIBS.");
   4292 
   4293 		gl.disableVertexArrayAttrib(max_attributes + 1, vao);
   4294 
   4295 		is_ok &= CheckError(
   4296 			GL_INVALID_OPERATION,
   4297 			"INVALID_VALUE was not generated by DisableVertexArrayAttrib if index is greater than MAX_VERTEX_ATTRIBS.");
   4298 	}
   4299 	catch (...)
   4300 	{
   4301 		is_ok	= false;
   4302 		is_error = true;
   4303 	}
   4304 
   4305 	/* Clean up. */
   4306 	if (vao)
   4307 	{
   4308 		gl.deleteVertexArrays(1, &vao);
   4309 	}
   4310 
   4311 	/* Errors clean up. */
   4312 	while (gl.getError())
   4313 		;
   4314 
   4315 	/* Result's setup. */
   4316 	if (is_ok)
   4317 	{
   4318 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4319 	}
   4320 	else
   4321 	{
   4322 		if (is_error)
   4323 		{
   4324 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   4325 		}
   4326 		else
   4327 		{
   4328 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4329 		}
   4330 	}
   4331 
   4332 	return STOP;
   4333 }
   4334 
   4335 /** @brief Compare error returned by GL with expected value and log.
   4336  *
   4337  *  @param [in] expected        Expected error.
   4338  *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
   4339  *
   4340  *  @return True if GL error is equal to expected, false otherwise.
   4341  */
   4342 bool EnableDisableAttributeErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message)
   4343 {
   4344 	/* Shortcut for GL functionality. */
   4345 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4346 
   4347 	glw::GLenum error = 0;
   4348 
   4349 	if (expected != (error = gl.getError()))
   4350 	{
   4351 		m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
   4352 											<< "was observed instead." << tcu::TestLog::EndMessage;
   4353 
   4354 		return false;
   4355 	}
   4356 
   4357 	return true;
   4358 }
   4359 
   4360 /******************************** Element Buffer Errors Test Implementation   ********************************/
   4361 
   4362 /** @brief Element Buffer Errors Test constructor.
   4363  *
   4364  *  @param [in] context     OpenGL context.
   4365  */
   4366 ElementBufferErrorsTest::ElementBufferErrorsTest(deqp::Context& context)
   4367 	: deqp::TestCase(context, "vertex_arrays_element_buffer_errors", "Element Buffer Errors Test")
   4368 {
   4369 }
   4370 
   4371 /** @brief Element Buffer Errors Test cases.
   4372  *
   4373  *  @return Iteration result.
   4374  */
   4375 tcu::TestNode::IterateResult ElementBufferErrorsTest::iterate()
   4376 {
   4377 	/* Shortcut for GL functionality. */
   4378 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4379 
   4380 	/* Get context setup. */
   4381 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
   4382 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
   4383 
   4384 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
   4385 	{
   4386 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
   4387 
   4388 		return STOP;
   4389 	}
   4390 
   4391 	/* Running tests. */
   4392 	bool is_ok	= true;
   4393 	bool is_error = false;
   4394 
   4395 	/* Tested Objects. */
   4396 	glw::GLuint vao		  = 0;
   4397 	glw::GLuint not_a_vao = 0;
   4398 	glw::GLuint bo		  = 0;
   4399 	glw::GLuint not_a_bo  = 0;
   4400 
   4401 	try
   4402 	{
   4403 		/* Prepare valid Objects. */
   4404 		gl.createVertexArrays(1, &vao);
   4405 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
   4406 
   4407 		gl.createBuffers(1, &bo);
   4408 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers call failed.");
   4409 
   4410 		/* Prepare invalid VAO. */
   4411 		while (gl.isVertexArray(++not_a_vao))
   4412 			;
   4413 		while (gl.isBuffer(++not_a_bo))
   4414 			;
   4415 
   4416 		/* Test not a VAO. */
   4417 		gl.vertexArrayElementBuffer(not_a_vao, bo);
   4418 
   4419 		is_ok &=
   4420 			CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error was not generated by VertexArrayElementBuffer if "
   4421 											 "vaobj is not the name of an existing vertex array object.");
   4422 
   4423 		/* Test not a BO. */
   4424 		gl.vertexArrayElementBuffer(vao, not_a_bo);
   4425 
   4426 		is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error is generated by VertexArrayElementBuffer if "
   4427 												  "buffer is not zero or the name of an existing buffer object.");
   4428 	}
   4429 	catch (...)
   4430 	{
   4431 		is_ok	= false;
   4432 		is_error = true;
   4433 	}
   4434 
   4435 	/* Clean up. */
   4436 	if (vao)
   4437 	{
   4438 		gl.deleteVertexArrays(1, &vao);
   4439 	}
   4440 
   4441 	if (bo)
   4442 	{
   4443 		gl.deleteBuffers(1, &bo);
   4444 	}
   4445 
   4446 	/* Errors clean up. */
   4447 	while (gl.getError())
   4448 		;
   4449 
   4450 	/* Result's setup. */
   4451 	if (is_ok)
   4452 	{
   4453 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4454 	}
   4455 	else
   4456 	{
   4457 		if (is_error)
   4458 		{
   4459 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   4460 		}
   4461 		else
   4462 		{
   4463 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4464 		}
   4465 	}
   4466 
   4467 	return STOP;
   4468 }
   4469 
   4470 /** @brief Compare error returned by GL with expected value and log.
   4471  *
   4472  *  @param [in] expected        Expected error.
   4473  *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
   4474  *
   4475  *  @return True if GL error is equal to expected, false otherwise.
   4476  */
   4477 bool ElementBufferErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message)
   4478 {
   4479 	/* Shortcut for GL functionality. */
   4480 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4481 
   4482 	glw::GLenum error = 0;
   4483 
   4484 	if (expected != (error = gl.getError()))
   4485 	{
   4486 		m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
   4487 											<< " was observed instead." << tcu::TestLog::EndMessage;
   4488 
   4489 		return false;
   4490 	}
   4491 
   4492 	return true;
   4493 }
   4494 
   4495 /******************************** Vertex Buffers Errors Test Implementation   ********************************/
   4496 
   4497 /** @brief Vertex Buffers Errors Test constructor.
   4498  *
   4499  *  @param [in] context     OpenGL context.
   4500  */
   4501 VertexBuffersErrorsTest::VertexBuffersErrorsTest(deqp::Context& context)
   4502 	: deqp::TestCase(context, "vertex_arrays_vertex_buffers_errors", "Vertex Buffers Errors Test")
   4503 {
   4504 }
   4505 
   4506 /** @brief Vertex Buffers Errors Test cases.
   4507  *
   4508  *  @return Iteration result.
   4509  */
   4510 tcu::TestNode::IterateResult VertexBuffersErrorsTest::iterate()
   4511 {
   4512 	/* Shortcut for GL functionality. */
   4513 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4514 
   4515 	/* Get context setup. */
   4516 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
   4517 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
   4518 
   4519 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
   4520 	{
   4521 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
   4522 
   4523 		return STOP;
   4524 	}
   4525 
   4526 	/* Running tests. */
   4527 	bool is_ok	= true;
   4528 	bool is_error = false;
   4529 
   4530 	/* Tested Objects. */
   4531 	glw::GLuint vao		  = 0;
   4532 	glw::GLuint not_a_vao = 0;
   4533 	glw::GLuint bo		  = 0;
   4534 	glw::GLuint not_a_bo  = 0;
   4535 
   4536 	/* Valid setup. */
   4537 	glw::GLintptr valid_offset = 0;
   4538 	glw::GLsizei  valid_stride = 1;
   4539 
   4540 	/* Limits. (Minimum values - OpenGL 4.5 Core Specification, Table 23.55) */
   4541 	glw::GLint max_vertex_attrib_bindings = 16;
   4542 	glw::GLint max_vertex_attrib_stride   = 2048;
   4543 
   4544 	try
   4545 	{
   4546 		/* Prepare valid Objects. */
   4547 		gl.createVertexArrays(1, &vao);
   4548 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
   4549 
   4550 		gl.createBuffers(1, &bo);
   4551 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateBuffers call failed.");
   4552 
   4553 		/* Prepare invalid VAO. */
   4554 		while (gl.isVertexArray(++not_a_vao))
   4555 			;
   4556 		while (gl.isBuffer(++not_a_bo))
   4557 			;
   4558 
   4559 		/* Prepare limits. */
   4560 		gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_vertex_attrib_bindings);
   4561 		gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_STRIDE, &max_vertex_attrib_stride);
   4562 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   4563 
   4564 		/* Invalid setup. */
   4565 		glw::GLintptr invalid_offset   = -1;
   4566 		glw::GLsizei  invalid_stride_0 = -1;
   4567 		glw::GLsizei  invalid_stride_1 = max_vertex_attrib_stride + 1;
   4568 
   4569 		/* Test not a VAO. */
   4570 		gl.vertexArrayVertexBuffer(not_a_vao, 0, bo, valid_offset, valid_stride);
   4571 
   4572 		is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffer if "
   4573 												  "vaobj is not the name of an existing vertex array object.");
   4574 
   4575 		gl.vertexArrayVertexBuffers(not_a_vao, 0, 1, &bo, &valid_offset, &valid_stride);
   4576 
   4577 		is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffers if "
   4578 												  "vaobj is not the name of an existing vertex array object.");
   4579 
   4580 		/* Test not a BO. */
   4581 		gl.vertexArrayVertexBuffer(vao, 0, not_a_bo, valid_offset, valid_stride);
   4582 
   4583 		is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffer if "
   4584 												  "vaobj is not the name of an existing vertex array object.");
   4585 
   4586 		gl.vertexArrayVertexBuffers(vao, 0, 1, &not_a_bo, &valid_offset, &valid_stride);
   4587 
   4588 		is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffers if "
   4589 												  "vaobj is not the name of an existing vertex array object.");
   4590 
   4591 		/* Test too big binding index. */
   4592 		gl.vertexArrayVertexBuffer(vao, max_vertex_attrib_bindings, bo, valid_offset, valid_stride);
   4593 
   4594 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayVertexBuffer if "
   4595 											  "bindingindex is equal to the value of MAX_VERTEX_ATTRIB_BINDINGS.");
   4596 
   4597 		gl.vertexArrayVertexBuffer(vao, max_vertex_attrib_bindings + 1, bo, valid_offset, valid_stride);
   4598 
   4599 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayVertexBuffer if "
   4600 											  "bindingindex is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS.");
   4601 
   4602 		gl.vertexArrayVertexBuffers(vao, max_vertex_attrib_bindings, 1, &bo, &valid_offset, &valid_stride);
   4603 
   4604 		is_ok &=
   4605 			CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayVertexBuffers if "
   4606 											 "first+count is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS.");
   4607 
   4608 		/* Test too big stride. */
   4609 		gl.vertexArrayVertexBuffer(vao, 0, bo, -1, valid_stride);
   4610 
   4611 		is_ok &= CheckError(GL_INVALID_VALUE,
   4612 							"INVALID_VALUE is generated by VertexArrayVertexBuffer if offset less than zero.");
   4613 
   4614 		gl.vertexArrayVertexBuffer(vao, 0, bo, valid_offset, -1);
   4615 
   4616 		is_ok &= CheckError(GL_INVALID_VALUE,
   4617 							"INVALID_VALUE is generated by VertexArrayVertexBuffer if stride is less than zero.");
   4618 
   4619 		gl.vertexArrayVertexBuffer(vao, 0, bo, valid_offset, max_vertex_attrib_stride + 1);
   4620 
   4621 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE is generated by VertexArrayVertexBuffer if stride is "
   4622 											  "greater than the value of MAX_VERTEX_ATTRIB_STRIDE.");
   4623 
   4624 		gl.vertexArrayVertexBuffers(vao, 0, 1, &bo, &invalid_offset, &valid_stride);
   4625 
   4626 		is_ok &=
   4627 			CheckError(GL_INVALID_VALUE,
   4628 					   "INVALID_VALUE is generated by VertexArrayVertexBuffers if any value in offsets is negative.");
   4629 
   4630 		gl.vertexArrayVertexBuffers(vao, 0, 1, &bo, &valid_offset, &invalid_stride_0);
   4631 
   4632 		is_ok &=
   4633 			CheckError(GL_INVALID_VALUE,
   4634 					   "INVALID_VALUE is generated by VertexArrayVertexBuffers if any value in strides is negative.");
   4635 
   4636 		gl.vertexArrayVertexBuffers(vao, 0, 1, &bo, &valid_offset, &invalid_stride_1);
   4637 
   4638 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE is generated by VertexArrayVertexBuffers if a value in "
   4639 											  "strides is greater than the value of MAX_VERTEX_ATTRIB_STRIDE.");
   4640 	}
   4641 	catch (...)
   4642 	{
   4643 		is_ok	= false;
   4644 		is_error = true;
   4645 	}
   4646 
   4647 	/* Clean up. */
   4648 	if (vao)
   4649 	{
   4650 		gl.deleteVertexArrays(1, &vao);
   4651 	}
   4652 
   4653 	if (bo)
   4654 	{
   4655 		gl.deleteBuffers(1, &bo);
   4656 	}
   4657 
   4658 	/* Errors clean up. */
   4659 	while (gl.getError())
   4660 		;
   4661 
   4662 	/* Result's setup. */
   4663 	if (is_ok)
   4664 	{
   4665 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4666 	}
   4667 	else
   4668 	{
   4669 		if (is_error)
   4670 		{
   4671 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   4672 		}
   4673 		else
   4674 		{
   4675 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4676 		}
   4677 	}
   4678 
   4679 	return STOP;
   4680 }
   4681 
   4682 /** @brief Compare error returned by GL with expected value and log.
   4683  *
   4684  *  @param [in] expected        Expected error.
   4685  *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
   4686  *
   4687  *  @return True if GL error is equal to expected, false otherwise.
   4688  */
   4689 bool VertexBuffersErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message)
   4690 {
   4691 	/* Shortcut for GL functionality. */
   4692 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4693 
   4694 	glw::GLenum error = 0;
   4695 
   4696 	if (expected != (error = gl.getError()))
   4697 	{
   4698 		m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
   4699 											<< " was observed instead." << tcu::TestLog::EndMessage;
   4700 
   4701 		return false;
   4702 	}
   4703 
   4704 	return true;
   4705 }
   4706 
   4707 /******************************** Attribute Format Errors Test Implementation   ********************************/
   4708 
   4709 /** @brief Attribute Format Errors Test constructor.
   4710  *
   4711  *  @param [in] context     OpenGL context.
   4712  */
   4713 AttributeFormatErrorsTest::AttributeFormatErrorsTest(deqp::Context& context)
   4714 	: deqp::TestCase(context, "vertex_arrays_attribute_format_errors", "Attribute Format Errors Test")
   4715 {
   4716 }
   4717 
   4718 /** @brief Attribute Format Errors Test cases.
   4719  *
   4720  *  @return Iteration result.
   4721  */
   4722 tcu::TestNode::IterateResult AttributeFormatErrorsTest::iterate()
   4723 {
   4724 	/* Shortcut for GL functionality. */
   4725 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   4726 
   4727 	/* Get context setup. */
   4728 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
   4729 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
   4730 
   4731 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
   4732 	{
   4733 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
   4734 
   4735 		return STOP;
   4736 	}
   4737 
   4738 	/* Running tests. */
   4739 	bool is_ok	= true;
   4740 	bool is_error = false;
   4741 
   4742 	/* Tested Objects. */
   4743 	glw::GLuint vao		  = 0;
   4744 	glw::GLuint not_a_vao = 0;
   4745 
   4746 	/* Limits. (Minimum values - OpenGL 4.5 Core Specification, Table 23.55) */
   4747 	glw::GLint max_vertex_attribs				 = 16;
   4748 	glw::GLint max_vertex_attrib_relative_offset = 2047;
   4749 
   4750 	/* Invalid values. */
   4751 	glw::GLenum bad_type = 0;
   4752 
   4753 	static const glw::GLenum accepted_types[] = { GL_BYTE,
   4754 												  GL_SHORT,
   4755 												  GL_INT,
   4756 												  GL_FIXED,
   4757 												  GL_FLOAT,
   4758 												  GL_HALF_FLOAT,
   4759 												  GL_DOUBLE,
   4760 												  GL_UNSIGNED_BYTE,
   4761 												  GL_UNSIGNED_SHORT,
   4762 												  GL_UNSIGNED_INT,
   4763 												  GL_INT_2_10_10_10_REV,
   4764 												  GL_UNSIGNED_INT_2_10_10_10_REV,
   4765 												  GL_UNSIGNED_INT_10F_11F_11F_REV };
   4766 
   4767 	{
   4768 		bool is_accepted_type = true;
   4769 		while (is_accepted_type)
   4770 		{
   4771 			bad_type++;
   4772 			is_accepted_type = false;
   4773 			for (glw::GLuint i = 0; i < sizeof(accepted_types) / sizeof(accepted_types); ++i)
   4774 			{
   4775 				if (accepted_types[i] == bad_type)
   4776 				{
   4777 					is_accepted_type = true;
   4778 					break;
   4779 				}
   4780 			}
   4781 		}
   4782 	}
   4783 
   4784 	try
   4785 	{
   4786 		/* Prepare valid Objects. */
   4787 		gl.createVertexArrays(1, &vao);
   4788 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
   4789 
   4790 		/* Prepare invalid VAO. */
   4791 		while (gl.isVertexArray(++not_a_vao))
   4792 			;
   4793 
   4794 		/* Prepare limits. */
   4795 		gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs);
   4796 		gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &max_vertex_attrib_relative_offset);
   4797 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   4798 
   4799 		/* TESTS OF VERTEXARRAYATTRIBFORMAT */
   4800 
   4801 		/* MAX_VERTEX_ATTRIBS < */
   4802 		gl.vertexArrayAttribFormat(vao, max_vertex_attribs, 1, GL_BYTE, GL_FALSE, 0);
   4803 
   4804 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribFormat if "
   4805 											  "attribindex is equal to the value of MAX_VERTEX_ATTRIBS.");
   4806 
   4807 		gl.vertexArrayAttribFormat(vao, max_vertex_attribs + 1, 1, GL_BYTE, GL_FALSE, 0);
   4808 
   4809 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribFormat if "
   4810 											  "attribindex is greater than the value of MAX_VERTEX_ATTRIBS.");
   4811 
   4812 		gl.vertexArrayAttribIFormat(vao, max_vertex_attribs, 1, GL_BYTE, 0);
   4813 
   4814 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if "
   4815 											  "attribindex is equal to the value of MAX_VERTEX_ATTRIBS.");
   4816 
   4817 		gl.vertexArrayAttribIFormat(vao, max_vertex_attribs + 1, 1, GL_BYTE, 0);
   4818 
   4819 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if "
   4820 											  "attribindex is greater than the value of MAX_VERTEX_ATTRIBS.");
   4821 
   4822 		gl.vertexArrayAttribLFormat(vao, max_vertex_attribs, 1, GL_DOUBLE, 0);
   4823 
   4824 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if "
   4825 											  "attribindex is equal to the value of MAX_VERTEX_ATTRIBS.");
   4826 
   4827 		gl.vertexArrayAttribLFormat(vao, max_vertex_attribs + 1, 1, GL_DOUBLE, 0);
   4828 
   4829 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if "
   4830 											  "attribindex is greater than the value of MAX_VERTEX_ATTRIBS.");
   4831 
   4832 		/* size */
   4833 		gl.vertexArrayAttribFormat(vao, 0, 0, GL_BYTE, GL_FALSE, 0);
   4834 
   4835 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttrib*Format if size is "
   4836 											  "not one of the accepted values (0).");
   4837 
   4838 		gl.vertexArrayAttribFormat(vao, 0, 5, GL_BYTE, GL_FALSE, 0);
   4839 
   4840 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttrib*Format if size is "
   4841 											  "not one of the accepted values (5).");
   4842 
   4843 		gl.vertexArrayAttribIFormat(vao, 0, 0, GL_BYTE, 0);
   4844 
   4845 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if size is "
   4846 											  "not one of the accepted values (0).");
   4847 
   4848 		gl.vertexArrayAttribIFormat(vao, 0, 5, GL_BYTE, 0);
   4849 
   4850 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if size is "
   4851 											  "not one of the accepted values (5).");
   4852 
   4853 		gl.vertexArrayAttribLFormat(vao, 0, 0, GL_DOUBLE, 0);
   4854 
   4855 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if size is "
   4856 											  "not one of the accepted values (0).");
   4857 
   4858 		gl.vertexArrayAttribLFormat(vao, 0, 5, GL_DOUBLE, 0);
   4859 
   4860 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if size is "
   4861 											  "not one of the accepted values (5).");
   4862 
   4863 		/* relative offset */
   4864 		gl.vertexArrayAttribFormat(vao, 0, 1, GL_BYTE, GL_FALSE, max_vertex_attrib_relative_offset + 1);
   4865 
   4866 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttrib*Format if "
   4867 											  "relativeoffset is greater than the value of "
   4868 											  "MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");
   4869 
   4870 		gl.vertexArrayAttribIFormat(vao, 0, 1, GL_BYTE, max_vertex_attrib_relative_offset + 1);
   4871 
   4872 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribIFormat if "
   4873 											  "relativeoffset is greater than the value of "
   4874 											  "MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");
   4875 
   4876 		gl.vertexArrayAttribLFormat(vao, 0, 1, GL_DOUBLE, max_vertex_attrib_relative_offset + 1);
   4877 
   4878 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribLFormat if "
   4879 											  "relativeoffset is greater than the value of "
   4880 											  "MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.");
   4881 
   4882 		/* type */
   4883 		gl.vertexArrayAttribFormat(vao, 0, 1, bad_type, GL_FALSE, 0);
   4884 
   4885 		is_ok &= CheckError(
   4886 			GL_INVALID_ENUM,
   4887 			"INVALID_ENUM was not generated by VertexArrayAttribFormat if type is not one of the accepted tokens.");
   4888 
   4889 		gl.vertexArrayAttribIFormat(vao, 0, 1, bad_type, 0);
   4890 
   4891 		is_ok &= CheckError(
   4892 			GL_INVALID_ENUM,
   4893 			"INVALID_ENUM was not generated by VertexArrayAttribIFormat if type is not one of the accepted tokens.");
   4894 
   4895 		gl.vertexArrayAttribLFormat(vao, 0, 1, bad_type, 0);
   4896 
   4897 		is_ok &= CheckError(
   4898 			GL_INVALID_ENUM,
   4899 			"INVALID_ENUM was not generated by VertexArrayAttribLFormat if type is not one of the accepted tokens.");
   4900 
   4901 		/* type UNSIGNED_INT_10F_11F_11F_REV case */
   4902 		gl.vertexArrayAttribIFormat(vao, 0, 1, GL_UNSIGNED_INT_10F_11F_11F_REV, 0);
   4903 
   4904 		is_ok &= CheckError(
   4905 			GL_INVALID_ENUM,
   4906 			"INVALID_ENUM was not generated by VertexArrayAttribIFormat if type is UNSIGNED_INT_10F_11F_11F_REV.");
   4907 
   4908 		gl.vertexArrayAttribLFormat(vao, 0, 1, GL_UNSIGNED_INT_10F_11F_11F_REV, 0);
   4909 
   4910 		is_ok &= CheckError(
   4911 			GL_INVALID_ENUM,
   4912 			"INVALID_ENUM was not generated by VertexArrayAttribLFormat if type is UNSIGNED_INT_10F_11F_11F_REV.");
   4913 
   4914 		/* Test not a VAO. */
   4915 		gl.vertexArrayAttribFormat(not_a_vao, 0, 1, GL_BYTE, GL_FALSE, 0);
   4916 
   4917 		is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if "
   4918 												  "vaobj is not the name of an existing vertex array object.");
   4919 
   4920 		gl.vertexArrayAttribIFormat(not_a_vao, 0, 1, GL_BYTE, 0);
   4921 
   4922 		is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribIFormat if "
   4923 												  "vaobj is not the name of an existing vertex array object.");
   4924 
   4925 		gl.vertexArrayAttribLFormat(not_a_vao, 0, 1, GL_DOUBLE, 0);
   4926 
   4927 		is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribLFormat if "
   4928 												  "vaobj is not the name of an existing vertex array object.");
   4929 
   4930 		/* BGRA */
   4931 		gl.vertexArrayAttribFormat(vao, 0, GL_BGRA, GL_BYTE, GL_TRUE, 0);
   4932 
   4933 		is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if "
   4934 												  "size is BGRA and type is not UNSIGNED_BYTE, INT_2_10_10_10_REV or "
   4935 												  "UNSIGNED_INT_2_10_10_10_REV.");
   4936 
   4937 		gl.vertexArrayAttribFormat(vao, 0, 1, GL_INT_2_10_10_10_REV, GL_TRUE, 0);
   4938 
   4939 		is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if "
   4940 												  "type is INT_2_10_10_10_REV and size is neither 4 nor BGRA.");
   4941 
   4942 		gl.vertexArrayAttribFormat(vao, 0, 1, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 0);
   4943 
   4944 		is_ok &=
   4945 			CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if type "
   4946 											 "is UNSIGNED_INT_2_10_10_10_REV and size is neither 4 nor BGRA.");
   4947 
   4948 		gl.vertexArrayAttribFormat(vao, 0, 1, GL_UNSIGNED_INT_10F_11F_11F_REV, GL_TRUE, 0);
   4949 
   4950 		is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribFormat if "
   4951 												  "type is UNSIGNED_INT_10F_11F_11F_REV and size is not 3.");
   4952 
   4953 		gl.vertexArrayAttribFormat(vao, 0, GL_BGRA, GL_UNSIGNED_BYTE, GL_FALSE, 0);
   4954 
   4955 		is_ok &= CheckError(
   4956 			GL_INVALID_OPERATION,
   4957 			"INVALID_OPERATION was not generated by VertexArrayAttribFormat if size is BGRA and normalized is FALSE.");
   4958 	}
   4959 	catch (...)
   4960 	{
   4961 		is_ok	= false;
   4962 		is_error = true;
   4963 	}
   4964 
   4965 	/* Clean up. */
   4966 	if (vao)
   4967 	{
   4968 		gl.deleteVertexArrays(1, &vao);
   4969 	}
   4970 
   4971 	/* Errors clean up. */
   4972 	while (gl.getError())
   4973 		;
   4974 
   4975 	/* Result's setup. */
   4976 	if (is_ok)
   4977 	{
   4978 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   4979 	}
   4980 	else
   4981 	{
   4982 		if (is_error)
   4983 		{
   4984 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   4985 		}
   4986 		else
   4987 		{
   4988 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   4989 		}
   4990 	}
   4991 
   4992 	return STOP;
   4993 }
   4994 
   4995 /** @brief Compare error returned by GL with expected value and log.
   4996  *
   4997  *  @param [in] expected        Expected error.
   4998  *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
   4999  *
   5000  *  @return True if GL error is equal to expected, false otherwise.
   5001  */
   5002 bool AttributeFormatErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message)
   5003 {
   5004 	/* Shortcut for GL functionality. */
   5005 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5006 
   5007 	glw::GLenum error = 0;
   5008 
   5009 	if (expected != (error = gl.getError()))
   5010 	{
   5011 		m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
   5012 											<< " was observed instead." << tcu::TestLog::EndMessage;
   5013 
   5014 		return false;
   5015 	}
   5016 
   5017 	return true;
   5018 }
   5019 
   5020 /******************************** Attribute Binding Errors Test Implementation   ********************************/
   5021 
   5022 /** @brief Attribute Binding Errors Test constructor.
   5023  *
   5024  *  @param [in] context     OpenGL context.
   5025  */
   5026 AttributeBindingErrorsTest::AttributeBindingErrorsTest(deqp::Context& context)
   5027 	: deqp::TestCase(context, "vertex_arrays_attribute_binding_errors", "Attribute Binding Errors Test")
   5028 {
   5029 }
   5030 
   5031 /** @brief Attribute Binding Errors Test cases.
   5032  *
   5033  *  @return Iteration result.
   5034  */
   5035 tcu::TestNode::IterateResult AttributeBindingErrorsTest::iterate()
   5036 {
   5037 	/* Shortcut for GL functionality. */
   5038 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5039 
   5040 	/* Get context setup. */
   5041 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
   5042 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
   5043 
   5044 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
   5045 	{
   5046 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
   5047 
   5048 		return STOP;
   5049 	}
   5050 
   5051 	/* Running tests. */
   5052 	bool is_ok	= true;
   5053 	bool is_error = false;
   5054 
   5055 	/* Tested Objects. */
   5056 	glw::GLuint vao		  = 0;
   5057 	glw::GLuint not_a_vao = 0;
   5058 
   5059 	/* Limits. (Minimum values - OpenGL 4.5 Core Specification, Table 23.55) */
   5060 	glw::GLint max_vertex_attribs		  = 16;
   5061 	glw::GLint max_vertex_attrib_bindings = 16;
   5062 
   5063 	try
   5064 	{
   5065 		/* Prepare valid Objects. */
   5066 		gl.createVertexArrays(1, &vao);
   5067 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
   5068 
   5069 		/* Prepare invalid VAO. */
   5070 		while (gl.isVertexArray(++not_a_vao))
   5071 			;
   5072 
   5073 		/* Prepare limits. */
   5074 		gl.getIntegerv(GL_MAX_VERTEX_ATTRIBS, &max_vertex_attribs);
   5075 		gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_vertex_attrib_bindings);
   5076 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   5077 
   5078 		/* Not a VAO. */
   5079 		gl.vertexArrayAttribBinding(not_a_vao, 0, 0);
   5080 
   5081 		is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayAttribBinding if "
   5082 												  "vaobj is not the name of an existing vertex array object.");
   5083 
   5084 		/* Too big attribute index. */
   5085 		gl.vertexArrayAttribBinding(vao, max_vertex_attribs, 0);
   5086 
   5087 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribBinding if "
   5088 											  "attribindex is equal to the value of MAX_VERTEX_ATTRIBS.");
   5089 
   5090 		gl.vertexArrayAttribBinding(vao, max_vertex_attribs + 1, 0);
   5091 
   5092 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribBinding if "
   5093 											  "attribindex is greater than the value of MAX_VERTEX_ATTRIBS.");
   5094 
   5095 		/* Too big binding index. */
   5096 		gl.vertexArrayAttribBinding(vao, 0, max_vertex_attrib_bindings);
   5097 
   5098 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribBinding if "
   5099 											  "bindingindex is equal to the value of MAX_VERTEX_ATTRIB_BINDINGS.");
   5100 
   5101 		gl.vertexArrayAttribBinding(vao, 0, max_vertex_attrib_bindings + 1);
   5102 
   5103 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayAttribBinding if "
   5104 											  "bindingindex is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS.");
   5105 	}
   5106 	catch (...)
   5107 	{
   5108 		is_ok	= false;
   5109 		is_error = true;
   5110 	}
   5111 
   5112 	/* Clean up. */
   5113 	if (vao)
   5114 	{
   5115 		gl.deleteVertexArrays(1, &vao);
   5116 	}
   5117 
   5118 	/* Errors clean up. */
   5119 	while (gl.getError())
   5120 		;
   5121 
   5122 	/* Result's setup. */
   5123 	if (is_ok)
   5124 	{
   5125 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5126 	}
   5127 	else
   5128 	{
   5129 		if (is_error)
   5130 		{
   5131 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   5132 		}
   5133 		else
   5134 		{
   5135 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5136 		}
   5137 	}
   5138 
   5139 	return STOP;
   5140 }
   5141 
   5142 /** @brief Compare error returned by GL with expected value and log.
   5143  *
   5144  *  @param [in] expected        Expected error.
   5145  *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
   5146  *
   5147  *  @return True if GL error is equal to expected, false otherwise.
   5148  */
   5149 bool AttributeBindingErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message)
   5150 {
   5151 	/* Shortcut for GL functionality. */
   5152 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5153 
   5154 	glw::GLenum error = 0;
   5155 
   5156 	if (expected != (error = gl.getError()))
   5157 	{
   5158 		m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
   5159 											<< " was observed instead." << tcu::TestLog::EndMessage;
   5160 
   5161 		return false;
   5162 	}
   5163 
   5164 	return true;
   5165 }
   5166 
   5167 /******************************** Attribute Binding Divisor Errors Test Implementation   ********************************/
   5168 
   5169 /** @brief Attribute Binding Divisor Errors Test constructor.
   5170  *
   5171  *  @param [in] context     OpenGL context.
   5172  */
   5173 AttributeBindingDivisorErrorsTest::AttributeBindingDivisorErrorsTest(deqp::Context& context)
   5174 	: deqp::TestCase(context, "vertex_arrays_attribute_binding_divisor_errors", "Attribute Binding Divisor Errors Test")
   5175 {
   5176 }
   5177 
   5178 /** @brief Attribute Binding Divisor Errors Test cases.
   5179  *
   5180  *  @return Iteration result.
   5181  */
   5182 tcu::TestNode::IterateResult AttributeBindingDivisorErrorsTest::iterate()
   5183 {
   5184 	/* Shortcut for GL functionality. */
   5185 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5186 
   5187 	/* Get context setup. */
   5188 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
   5189 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
   5190 
   5191 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
   5192 	{
   5193 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
   5194 
   5195 		return STOP;
   5196 	}
   5197 
   5198 	/* Running tests. */
   5199 	bool is_ok	= true;
   5200 	bool is_error = false;
   5201 
   5202 	/* Tested Objects. */
   5203 	glw::GLuint vao		  = 0;
   5204 	glw::GLuint not_a_vao = 0;
   5205 
   5206 	/* Limits. (Minimum values - OpenGL 4.5 Core Specification, Table 23.55) */
   5207 	glw::GLint max_vertex_attrib_bindings = 16;
   5208 
   5209 	try
   5210 	{
   5211 		/* Prepare valid Objects. */
   5212 		gl.createVertexArrays(1, &vao);
   5213 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
   5214 
   5215 		/* Prepare invalid VAO. */
   5216 		while (gl.isVertexArray(++not_a_vao))
   5217 			;
   5218 
   5219 		/* Prepare limits. */
   5220 		gl.getIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_vertex_attrib_bindings);
   5221 		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv call failed.");
   5222 
   5223 		/* Not a VAO. */
   5224 		gl.vertexArrayBindingDivisor(not_a_vao, 0, 0);
   5225 
   5226 		is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION was not generated by VertexArrayBindingDivisor if "
   5227 												  "vaobj is not the name of an existing vertex array object.");
   5228 
   5229 		/* Too big binding index. */
   5230 		gl.vertexArrayBindingDivisor(vao, max_vertex_attrib_bindings, 0);
   5231 
   5232 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayBindingDivisor if "
   5233 											  "bindingindex is equal to the value of MAX_VERTEX_ATTRIB_BINDINGS.");
   5234 
   5235 		gl.vertexArrayBindingDivisor(vao, max_vertex_attrib_bindings + 1, 0);
   5236 
   5237 		is_ok &= CheckError(GL_INVALID_VALUE, "INVALID_VALUE was not generated by VertexArrayBindingDivisor if "
   5238 											  "bindingindex is greater than the value of MAX_VERTEX_ATTRIB_BINDINGS.");
   5239 	}
   5240 	catch (...)
   5241 	{
   5242 		is_ok	= false;
   5243 		is_error = true;
   5244 	}
   5245 
   5246 	/* Clean up. */
   5247 	if (vao)
   5248 	{
   5249 		gl.deleteVertexArrays(1, &vao);
   5250 	}
   5251 
   5252 	/* Errors clean up. */
   5253 	while (gl.getError())
   5254 		;
   5255 
   5256 	/* Result's setup. */
   5257 	if (is_ok)
   5258 	{
   5259 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5260 	}
   5261 	else
   5262 	{
   5263 		if (is_error)
   5264 		{
   5265 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   5266 		}
   5267 		else
   5268 		{
   5269 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5270 		}
   5271 	}
   5272 
   5273 	return STOP;
   5274 }
   5275 
   5276 /** @brief Compare error returned by GL with expected value and log.
   5277  *
   5278  *  @param [in] expected        Expected error.
   5279  *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
   5280  *
   5281  *  @return True if GL error is equal to expected, false otherwise.
   5282  */
   5283 bool AttributeBindingDivisorErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message)
   5284 {
   5285 	/* Shortcut for GL functionality. */
   5286 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5287 
   5288 	glw::GLenum error = 0;
   5289 
   5290 	if (expected != (error = gl.getError()))
   5291 	{
   5292 		m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
   5293 											<< " was observed instead." << tcu::TestLog::EndMessage;
   5294 
   5295 		return false;
   5296 	}
   5297 
   5298 	return true;
   5299 }
   5300 
   5301 /******************************** Get Vertex Array Errors Test Implementation   ********************************/
   5302 
   5303 /** @brief Get Vertex Array Errors Test constructor.
   5304  *
   5305  *  @param [in] context     OpenGL context.
   5306  */
   5307 GetVertexArrayErrorsTest::GetVertexArrayErrorsTest(deqp::Context& context)
   5308 	: deqp::TestCase(context, "vertex_arrays_get_vertex_array_errors", "Get Vertex Array Errors Test")
   5309 {
   5310 }
   5311 
   5312 /** @brief Iterate over Get Vertex Array Errors Test cases.
   5313  *
   5314  *  @return Iteration result.
   5315  */
   5316 tcu::TestNode::IterateResult GetVertexArrayErrorsTest::iterate()
   5317 {
   5318 	/* Shortcut for GL functionality. */
   5319 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5320 
   5321 	/* Get context setup. */
   5322 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
   5323 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
   5324 
   5325 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
   5326 	{
   5327 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
   5328 
   5329 		return STOP;
   5330 	}
   5331 
   5332 	/* Running tests. */
   5333 	bool is_ok	= true;
   5334 	bool is_error = false;
   5335 
   5336 	/* Tested Objects. */
   5337 	glw::GLuint vao		  = 0;
   5338 	glw::GLuint not_a_vao = 0;
   5339 
   5340 	glw::GLint storage = 0;
   5341 
   5342 	try
   5343 	{
   5344 		/* Prepare valid Objects. */
   5345 		gl.createVertexArrays(1, &vao);
   5346 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
   5347 
   5348 		/* Prepare invalid VAO. */
   5349 		while (gl.isVertexArray(++not_a_vao))
   5350 			;
   5351 
   5352 		/* Not a VAO. */
   5353 		gl.getVertexArrayiv(not_a_vao, GL_ELEMENT_ARRAY_BUFFER_BINDING, &storage);
   5354 
   5355 		is_ok &= CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error was not generated by GetVertexArrayiv if "
   5356 												  "vaobj is not the name of an existing vertex array object.");
   5357 
   5358 		/* Bad parameter. */
   5359 		gl.getVertexArrayiv(vao, GL_ELEMENT_ARRAY_BUFFER_BINDING + 1, &storage);
   5360 
   5361 		is_ok &= CheckError(
   5362 			GL_INVALID_ENUM,
   5363 			"INVALID_ENUM error was not generated by GetVertexArrayiv if pname is not ELEMENT_ARRAY_BUFFER_BINDING.");
   5364 	}
   5365 	catch (...)
   5366 	{
   5367 		is_ok	= false;
   5368 		is_error = true;
   5369 	}
   5370 
   5371 	/* Clean up. */
   5372 	if (vao)
   5373 	{
   5374 		gl.deleteVertexArrays(1, &vao);
   5375 	}
   5376 
   5377 	/* Errors clean up. */
   5378 	while (gl.getError())
   5379 		;
   5380 
   5381 	/* Result's setup. */
   5382 	if (is_ok)
   5383 	{
   5384 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5385 	}
   5386 	else
   5387 	{
   5388 		if (is_error)
   5389 		{
   5390 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   5391 		}
   5392 		else
   5393 		{
   5394 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5395 		}
   5396 	}
   5397 
   5398 	return STOP;
   5399 }
   5400 
   5401 /** @brief Compare error returned by GL with expected value and log.
   5402  *
   5403  *  @param [in] expected        Expected error.
   5404  *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
   5405  *
   5406  *  @return True if GL error is equal to expected, false otherwise.
   5407  */
   5408 bool GetVertexArrayErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message)
   5409 {
   5410 	/* Shortcut for GL functionality. */
   5411 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5412 
   5413 	glw::GLenum error = 0;
   5414 
   5415 	if (expected != (error = gl.getError()))
   5416 	{
   5417 		m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
   5418 											<< " was observed instead." << tcu::TestLog::EndMessage;
   5419 
   5420 		return false;
   5421 	}
   5422 
   5423 	return true;
   5424 }
   5425 
   5426 /******************************** Get Vertex Array Indexed Errors Test Implementation   ********************************/
   5427 
   5428 /** @brief Get Vertex Array Indexed Errors Test constructor.
   5429  *
   5430  *  @param [in] context     OpenGL context.
   5431  */
   5432 GetVertexArrayIndexedErrorsTest::GetVertexArrayIndexedErrorsTest(deqp::Context& context)
   5433 	: deqp::TestCase(context, "vertex_arrays_get_vertex_array_indexed_errors", "Get Vertex Array Indexed Errors Test")
   5434 {
   5435 }
   5436 
   5437 /** @brief Iterate over Get Vertex Array Indexed Errors Test cases.
   5438  *
   5439  *  @return Iteration result.
   5440  */
   5441 tcu::TestNode::IterateResult GetVertexArrayIndexedErrorsTest::iterate()
   5442 {
   5443 	/* Shortcut for GL functionality. */
   5444 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5445 
   5446 	/* Get context setup. */
   5447 	bool is_at_least_gl_45 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 5)));
   5448 	bool is_arb_direct_state_access = m_context.getContextInfo().isExtensionSupported("GL_ARB_direct_state_access");
   5449 
   5450 	if ((!is_at_least_gl_45) && (!is_arb_direct_state_access))
   5451 	{
   5452 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not Supported");
   5453 
   5454 		return STOP;
   5455 	}
   5456 
   5457 	/* Running tests. */
   5458 	bool is_ok	= true;
   5459 	bool is_error = false;
   5460 
   5461 	/* Tested Objects. */
   5462 	glw::GLuint vao		  = 0;
   5463 	glw::GLuint not_a_vao = 0;
   5464 
   5465 	/* Dummy storage. */
   5466 	glw::GLint   storage   = 0;
   5467 	glw::GLint64 storage64 = 0;
   5468 
   5469 	/* Bad parameter setup. */
   5470 	glw::GLenum bad_pname = 0;
   5471 
   5472 	static const glw::GLenum accepted_pnames[] = { GL_VERTEX_ATTRIB_ARRAY_ENABLED,	GL_VERTEX_ATTRIB_ARRAY_SIZE,
   5473 												   GL_VERTEX_ATTRIB_ARRAY_STRIDE,	 GL_VERTEX_ATTRIB_ARRAY_TYPE,
   5474 												   GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, GL_VERTEX_ATTRIB_ARRAY_INTEGER,
   5475 												   GL_VERTEX_ATTRIB_ARRAY_LONG,		  GL_VERTEX_ATTRIB_ARRAY_DIVISOR,
   5476 												   GL_VERTEX_ATTRIB_RELATIVE_OFFSET };
   5477 
   5478 	{
   5479 		bool is_accepted_pname = true;
   5480 		while (is_accepted_pname)
   5481 		{
   5482 			bad_pname++;
   5483 			is_accepted_pname = false;
   5484 			for (glw::GLuint i = 0; i < sizeof(accepted_pnames) / sizeof(accepted_pnames); ++i)
   5485 			{
   5486 				if (accepted_pnames[i] == bad_pname)
   5487 				{
   5488 					is_accepted_pname = true;
   5489 					break;
   5490 				}
   5491 			}
   5492 		}
   5493 	}
   5494 
   5495 	try
   5496 	{
   5497 		/* Prepare valid Objects. */
   5498 		gl.createVertexArrays(1, &vao);
   5499 		GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateVertexArrays call failed.");
   5500 
   5501 		/* Prepare invalid VAO. */
   5502 		while (gl.isVertexArray(++not_a_vao))
   5503 			;
   5504 
   5505 		/* Not a VAO. */
   5506 		gl.getVertexArrayIndexediv(not_a_vao, 0, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &storage);
   5507 
   5508 		is_ok &=
   5509 			CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error was not generated by GetVertexArrayIndexediv if "
   5510 											 "vaobj is not the name of an existing vertex array object.");
   5511 
   5512 		gl.getVertexArrayIndexed64iv(not_a_vao, 0, GL_VERTEX_BINDING_OFFSET, &storage64);
   5513 
   5514 		is_ok &=
   5515 			CheckError(GL_INVALID_OPERATION, "INVALID_OPERATION error was not generated by GetVertexArrayIndexed64iv "
   5516 											 "if vaobj is not the name of an existing vertex array object.");
   5517 
   5518 		/* Bad parameter. */
   5519 		gl.getVertexArrayIndexediv(vao, 0, bad_pname, &storage);
   5520 
   5521 		is_ok &= CheckError(
   5522 			GL_INVALID_ENUM,
   5523 			"INVALID_ENUM error was not generated by GetVertexArrayIndexediv if pname is not one of the valid values.");
   5524 
   5525 		/* Bad parameter 64. */
   5526 		gl.getVertexArrayIndexed64iv(vao, 0, GL_VERTEX_BINDING_OFFSET + 1, &storage64);
   5527 
   5528 		is_ok &= CheckError(
   5529 			GL_INVALID_ENUM,
   5530 			"INVALID_ENUM error was not generated by GetVertexArrayIndexed64iv if pname is not VERTEX_BINDING_OFFSET.");
   5531 	}
   5532 	catch (...)
   5533 	{
   5534 		is_ok	= false;
   5535 		is_error = true;
   5536 	}
   5537 
   5538 	/* Clean up. */
   5539 	if (vao)
   5540 	{
   5541 		gl.deleteVertexArrays(1, &vao);
   5542 	}
   5543 
   5544 	/* Errors clean up. */
   5545 	while (gl.getError())
   5546 		;
   5547 
   5548 	/* Result's setup. */
   5549 	if (is_ok)
   5550 	{
   5551 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   5552 	}
   5553 	else
   5554 	{
   5555 		if (is_error)
   5556 		{
   5557 			m_testCtx.setTestResult(QP_TEST_RESULT_INTERNAL_ERROR, "Error");
   5558 		}
   5559 		else
   5560 		{
   5561 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   5562 		}
   5563 	}
   5564 
   5565 	return STOP;
   5566 }
   5567 
   5568 /** @brief Compare error returned by GL with expected value and log.
   5569  *
   5570  *  @param [in] expected        Expected error.
   5571  *  @param [in] log_message   Message to be logged if expected error is not the equal to the reported one.
   5572  *
   5573  *  @return True if GL error is equal to expected, false otherwise.
   5574  */
   5575 bool GetVertexArrayIndexedErrorsTest::CheckError(const glw::GLenum expected, const glw::GLchar* log_message)
   5576 {
   5577 	/* Shortcut for GL functionality. */
   5578 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
   5579 
   5580 	glw::GLenum error = 0;
   5581 
   5582 	if (expected != (error = gl.getError()))
   5583 	{
   5584 		m_context.getTestContext().getLog() << tcu::TestLog::Message << log_message << " " << glu::getErrorStr(error)
   5585 											<< " was observed instead." << tcu::TestLog::EndMessage;
   5586 
   5587 		return false;
   5588 	}
   5589 
   5590 	return true;
   5591 }
   5592 } /* VertexArrays namespace. */
   5593 } /* DirectStateAccess namespace. */
   5594 } /* gl4cts namespace. */
   5595