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
56namespace gl4cts
57{
58namespace DirectStateAccess
59{
60namespace VertexArrays
61{
62/******************************** Creation Test Implementation   ********************************/
63
64/** @brief Creation Test constructor.
65 *
66 *  @param [in] context     OpenGL context.
67 */
68CreationTest::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 */
78tcu::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 */
195EnableDisableAttributesTest::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 */
212tcu::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
282glw::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 */
307glw::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 = DE_LENGTH_OF_ARRAY(shader);
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 */
472void 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								glu::BufferOffsetAsPointer(i * sizeof(glw::GLint)));
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 */
521void 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 */
547bool 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 */
619bool 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. */
692void 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
744std::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
757std::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
771const 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
781const 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 */
796ElementBufferTest::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 */
811tcu::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 */
875void 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 = DE_LENGTH_OF_ARRAY(shader);
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 */
1030bool 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 */
1092void 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 */
1116bool 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. */
1165void 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
1211const 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
1222const 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 */
1237VertexBuffersTest::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 */
1252tcu::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 */
1322void 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 = DE_LENGTH_OF_ARRAY(shader);
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 */
1479bool 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] = { 0, sizeof(glw::GLint) };
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, sizeof(glw::GLint),
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 */
1624void 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 */
1648bool 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. */
1699void 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
1745const 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
1759const 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 */
1774AttributeFormatTest::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 */
1788tcu::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 */
1947void 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 = DE_LENGTH_OF_ARRAY(shader);
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
2103template <>
2104glw::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
2109template <>
2110glw::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
2115template <>
2116glw::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
2121template <>
2122glw::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
2127template <>
2128glw::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
2133template <>
2134glw::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
2139template <typename T>
2140glw::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 */
2153template <typename T>
2154bool 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, size * sizeof(T),
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 */
2254void 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
2288template <>
2289bool 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
2299template <>
2300bool 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
2310template <typename T>
2311bool 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 */
2323template <typename T>
2324bool 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. */
2434void 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. */
2450void 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. */
2471void 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
2487const glw::GLchar* AttributeFormatTest::s_vertex_shader_head = "#version 450\n"
2488															   "\n";
2489
2490const 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
2497const 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
2550const 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 */
2565AttributeBindingTest::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 */
2579tcu::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 */
2643void 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 = DE_LENGTH_OF_ARRAY(shader);
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 */
2802bool 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, glu::BufferOffsetAsPointer(1 * sizeof(glw::GLint)));
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 */
2856void 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 */
2880bool 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. */
2922void 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
2961const 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
2974const 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 */
2989AttributeBindingDivisorTest::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 */
3003tcu::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 */
3106void 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 */
3265void 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 */
3304void 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 */
3329void 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 */
3353bool 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 */
3382bool 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. */
3437void 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
3476const 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
3487const 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 */
3502GetVertexArrayTest::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 */
3512tcu::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 */
3618GetVertexArrayIndexedTest::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 */
3631tcu::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 */
3751void 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, glu::BufferOffsetAsPointer(2 * sizeof(glw::GLchar)));
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, glu::BufferOffsetAsPointer(4 * sizeof(glw::GLchar)));
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 */
3832bool 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 */
3872bool 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 */
3910DefaultsTest::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 */
3919tcu::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 */
4009void 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 */
4025bool 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 */
4056bool 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 */
4087bool 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 */
4116CreationErrorTest::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 */
4125tcu::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 */
4190bool 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 */
4214EnableDisableAttributeErrorsTest::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 */
4223tcu::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 */
4342bool 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 */
4366ElementBufferErrorsTest::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 */
4375tcu::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 */
4477bool 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 */
4501VertexBuffersErrorsTest::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 */
4510tcu::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 */
4689bool 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 */
4713AttributeFormatErrorsTest::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 */
4722tcu::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 < DE_LENGTH_OF_ARRAY(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 */
5002bool 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 */
5026AttributeBindingErrorsTest::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 */
5035tcu::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 */
5149bool 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 */
5173AttributeBindingDivisorErrorsTest::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 */
5182tcu::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 */
5283bool 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 */
5307GetVertexArrayErrorsTest::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 */
5316tcu::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 */
5408bool 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 */
5432GetVertexArrayIndexedErrorsTest::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 */
5441tcu::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	/* Unused 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 < DE_LENGTH_OF_ARRAY(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 */
5575bool 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