1/*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
4 *
5 * Copyright (c) 2014-2016 The Khronos Group Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 */ /*!
20 * \file
21 * \brief
22 */ /*-------------------------------------------------------------------*/
23
24#include "gl4cVertexAttribBindingTests.hpp"
25#include "glwEnums.hpp"
26#include "tcuMatrix.hpp"
27#include "tcuRenderTarget.hpp"
28#include <cstdarg>
29
30#include <cmath>
31
32namespace gl4cts
33{
34
35using namespace glw;
36using tcu::Vec4;
37using tcu::IVec4;
38using tcu::UVec4;
39using tcu::DVec4;
40using tcu::Vec3;
41using tcu::IVec3;
42using tcu::DVec3;
43using tcu::Vec2;
44using tcu::IVec2;
45using tcu::UVec2;
46using tcu::Mat4;
47
48namespace
49{
50
51class VertexAttribBindingBase : public deqp::SubcaseBase
52{
53
54	virtual std::string Title()
55	{
56		return NL "";
57	}
58
59	virtual std::string Purpose()
60	{
61		return NL "";
62	}
63
64	virtual std::string Method()
65	{
66		return NL "";
67	}
68
69	virtual std::string PassCriteria()
70	{
71		return NL "";
72	}
73
74public:
75	int getWindowWidth()
76	{
77		const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
78		return renderTarget.getWidth();
79	}
80
81	int getWindowHeight()
82	{
83		const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
84		return renderTarget.getHeight();
85	}
86
87	inline bool ColorEqual(const Vec4& c0, const Vec4& c1, const Vec4& epsilon)
88	{
89		if (fabs(c0[0] - c1[0]) > epsilon[0])
90			return false;
91		if (fabs(c0[1] - c1[1]) > epsilon[1])
92			return false;
93		if (fabs(c0[2] - c1[2]) > epsilon[2])
94			return false;
95		if (fabs(c0[3] - c1[3]) > epsilon[3])
96			return false;
97		return true;
98	}
99
100	inline bool ColorEqual(const Vec3& c0, const Vec3& c1, const Vec4& epsilon)
101	{
102		if (fabs(c0[0] - c1[0]) > epsilon[0])
103			return false;
104		if (fabs(c0[1] - c1[1]) > epsilon[1])
105			return false;
106		if (fabs(c0[2] - c1[2]) > epsilon[2])
107			return false;
108		return true;
109	}
110
111	bool CheckRectColor(const std::vector<Vec3>& fb, int fb_w, int rx, int ry, int rw, int rh, const Vec3& expected)
112	{
113
114		const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
115		const tcu::PixelFormat&  pixelFormat  = renderTarget.getPixelFormat();
116		Vec4					 g_color_eps  = Vec4(
117			1.f / static_cast<float>(1 << pixelFormat.redBits), 1.f / static_cast<float>(1 << pixelFormat.greenBits),
118			1.f / static_cast<float>(1 << pixelFormat.blueBits), 1.f / static_cast<float>(1 << pixelFormat.alphaBits));
119
120		for (int y = ry; y < ry + rh; ++y)
121		{
122			for (int x = rx; x < rx + rw; ++x)
123			{
124				const int idx = y * fb_w + x;
125				if (!ColorEqual(fb[idx], expected, g_color_eps))
126				{
127					m_context.getTestContext().getLog()
128						<< tcu::TestLog::Message << "Incorrect framebuffer color at pixel (" << x << " " << y
129						<< "). Color is (" << fb[idx][0] << " " << fb[idx][1] << " " << fb[idx][2]
130						<< "). Color should be (" << expected[0] << " " << expected[1] << " " << expected[2] << ")"
131						<< tcu::TestLog::EndMessage;
132					return false;
133				}
134			}
135		}
136		return true;
137	}
138
139	bool CheckRectColor(const std::vector<Vec4>& fb, int fb_w, int rx, int ry, int rw, int rh, const Vec4& expected)
140	{
141		const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
142		const tcu::PixelFormat&  pixelFormat  = renderTarget.getPixelFormat();
143		Vec4					 g_color_eps  = Vec4(
144			1.f / static_cast<float>(1 << pixelFormat.redBits), 1.f / static_cast<float>(1 << pixelFormat.greenBits),
145			1.f / static_cast<float>(1 << pixelFormat.blueBits), 1.f / static_cast<float>(1 << pixelFormat.alphaBits));
146
147		for (int y = ry; y < ry + rh; ++y)
148		{
149			for (int x = rx; x < rx + rw; ++x)
150			{
151				const int idx = y * fb_w + x;
152				if (!ColorEqual(fb[idx], expected, g_color_eps))
153				{
154					m_context.getTestContext().getLog()
155						<< tcu::TestLog::Message << "Incorrect framebuffer color at pixel (" << x << " " << y
156						<< "). Color is (" << fb[idx][0] << " " << fb[idx][1] << " " << fb[idx][2] << " " << fb[idx][3]
157						<< "). Color should be (" << expected[0] << " " << expected[1] << " " << expected[2] << " "
158						<< expected[3] << ")" << tcu::TestLog::EndMessage;
159					return false;
160				}
161			}
162		}
163		return true;
164	}
165
166	bool CheckProgram(GLuint program)
167	{
168		GLint status;
169		glGetProgramiv(program, GL_LINK_STATUS, &status);
170
171		if (status == GL_FALSE)
172		{
173			GLint attached_shaders;
174			glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
175
176			if (attached_shaders > 0)
177			{
178				std::vector<GLuint> shaders(attached_shaders);
179				glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
180
181				for (GLint i = 0; i < attached_shaders; ++i)
182				{
183					GLenum type;
184					glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type));
185					switch (type)
186					{
187					case GL_VERTEX_SHADER:
188						m_context.getTestContext().getLog()
189							<< tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
190						break;
191					case GL_TESS_CONTROL_SHADER:
192						m_context.getTestContext().getLog()
193							<< tcu::TestLog::Message << "*** Tessellation Control Shader ***"
194							<< tcu::TestLog::EndMessage;
195						break;
196					case GL_TESS_EVALUATION_SHADER:
197						m_context.getTestContext().getLog()
198							<< tcu::TestLog::Message << "*** Tessellation Evaluation Shader ***"
199							<< tcu::TestLog::EndMessage;
200						break;
201					case GL_GEOMETRY_SHADER:
202						m_context.getTestContext().getLog()
203							<< tcu::TestLog::Message << "*** Geometry Shader ***" << tcu::TestLog::EndMessage;
204						break;
205					case GL_FRAGMENT_SHADER:
206						m_context.getTestContext().getLog()
207							<< tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
208						break;
209					case GL_COMPUTE_SHADER:
210						m_context.getTestContext().getLog()
211							<< tcu::TestLog::Message << "*** Compute Shader ***" << tcu::TestLog::EndMessage;
212						break;
213					default:
214						m_context.getTestContext().getLog()
215							<< tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
216						break;
217					}
218					GLint length;
219					glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
220					if (length > 0)
221					{
222						std::vector<GLchar> source(length);
223						glGetShaderSource(shaders[i], length, NULL, &source[0]);
224						m_context.getTestContext().getLog()
225							<< tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
226					}
227					glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
228					if (length > 0)
229					{
230						std::vector<GLchar> log(length);
231						glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
232						m_context.getTestContext().getLog()
233							<< tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
234					}
235				}
236			}
237			GLint length;
238			glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
239			if (length > 0)
240			{
241				std::vector<GLchar> log(length);
242				glGetProgramInfoLog(program, length, NULL, &log[0]);
243				m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
244			}
245		}
246		return status == GL_TRUE ? true : false;
247	}
248
249	bool IsEqual(IVec4 a, IVec4 b)
250	{
251		return (a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]);
252	}
253
254	bool IsEqual(UVec4 a, UVec4 b)
255	{
256		return (a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]);
257	}
258
259	bool IsEqual(Vec2 a, Vec2 b)
260	{
261		return (a[0] == b[0]) && (a[1] == b[1]);
262	}
263
264	bool IsEqual(IVec2 a, IVec2 b)
265	{
266		return (a[0] == b[0]) && (a[1] == b[1]);
267	}
268
269	bool IsEqual(UVec2 a, UVec2 b)
270	{
271		return (a[0] == b[0]) && (a[1] == b[1]);
272	}
273
274	const Mat4 Translation(float tx, float ty, float tz)
275	{
276		float d[] = { 1.0f, 0.0f, 0.0f, tx, 0.0f, 1.0f, 0.0f, ty, 0.0f, 0.0f, 1.0f, tz, 0.0f, 0.0f, 0.0f, 1.0f };
277		return Mat4(d);
278	}
279};
280
281//=============================================================================
282// 1.1 BasicUsage
283//-----------------------------------------------------------------------------
284class BasicUsage : public VertexAttribBindingBase
285{
286	GLuint m_vsp, m_fsp, m_ppo, m_vao, m_vbo;
287
288	virtual long Setup()
289	{
290		m_vsp = m_fsp = 0;
291		glGenProgramPipelines(1, &m_ppo);
292		glGenVertexArrays(1, &m_vao);
293		glGenBuffers(1, &m_vbo);
294		return NO_ERROR;
295	}
296
297	virtual long Cleanup()
298	{
299		glDeleteProgram(m_vsp);
300		glDeleteProgram(m_fsp);
301		glDeleteProgramPipelines(1, &m_ppo);
302		glDeleteVertexArrays(1, &m_vao);
303		glDeleteBuffers(1, &m_vbo);
304		return NO_ERROR;
305	}
306
307	virtual long Run()
308	{
309		const char* const glsl_vs =
310			"#version 430 core" NL "layout(location = 0) in vec4 vs_in_position;" NL
311			"layout(location = 1) in vec3 vs_in_color;" NL "out StageData {" NL "  vec3 color;" NL "} vs_out;" NL
312			"out gl_PerVertex { vec4 gl_Position; };" NL "void main() {" NL "  gl_Position = vs_in_position;" NL
313			"  vs_out.color = vs_in_color;" NL "}";
314		const char* const glsl_fs = "#version 430 core" NL "in StageData {" NL "  vec3 color;" NL "} fs_in;" NL
315									"layout(location = 0) out vec4 fs_out_color;" NL "void main() {" NL
316									"  fs_out_color = vec4(fs_in.color, 1);" NL "}";
317		m_vsp = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);
318		m_fsp = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &glsl_fs);
319		if (!CheckProgram(m_vsp) || !CheckProgram(m_fsp))
320			return ERROR;
321
322		glUseProgramStages(m_ppo, GL_VERTEX_SHADER_BIT, m_vsp);
323		glUseProgramStages(m_ppo, GL_FRAGMENT_SHADER_BIT, m_fsp);
324
325		{
326			const float data[] = {
327				-1.0f, -1.0f, 0.0f,  1.0f, 0.0f, 1.0f, -1.0f, 0.0f,  1.0f, 0.0f, -1.0f, 1.0f, 0.0f,  1.0f,
328				0.0f,  1.0f,  1.0f,  0.0f, 1.0f, 0.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f,  1.0f, -1.0f, 1.0f,
329				1.0f,  0.0f,  -1.0f, 1.0f, 1.0f, 1.0f, 0.0f,  1.0f,  1.0f, 1.0f, 1.0f,  0.0f,
330			};
331			glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
332			glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
333			glBindBuffer(GL_ARRAY_BUFFER, 0);
334		}
335		glBindVertexArray(m_vao);
336		glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
337		glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 8);
338		glVertexAttribBinding(0, 0);
339		glVertexAttribBinding(1, 0);
340		glBindVertexBuffer(0, m_vbo, 0, 20);
341		glEnableVertexAttribArray(0);
342		glEnableVertexAttribArray(1);
343		glBindVertexArray(0);
344
345		glClear(GL_COLOR_BUFFER_BIT);
346		glBindVertexArray(m_vao);
347		glBindProgramPipeline(m_ppo);
348		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
349
350		bool			  status = true;
351		std::vector<Vec3> fb(getWindowWidth() * getWindowHeight());
352		glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
353		if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 1, 0)))
354			status = false;
355		if (!status)
356			return ERROR;
357
358		glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
359		glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
360		if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(1, 1, 0)))
361			status = false;
362		if (!status)
363			return ERROR;
364
365		return NO_ERROR;
366	}
367};
368
369//=============================================================================
370// BasicInputBase
371//-----------------------------------------------------------------------------
372class BasicInputBase : public VertexAttribBindingBase
373{
374	GLuint m_po, m_xfbo;
375
376protected:
377	Vec4	expected_data[64];
378	GLsizei instance_count;
379	GLint   base_instance;
380
381	virtual long Setup()
382	{
383		m_po = 0;
384		glGenBuffers(1, &m_xfbo);
385		for (int i			 = 0; i < 64; ++i)
386			expected_data[i] = Vec4(0.0f);
387		instance_count		 = 1;
388		base_instance		 = -1;
389		return NO_ERROR;
390	}
391
392	virtual long Cleanup()
393	{
394		glDisable(GL_RASTERIZER_DISCARD);
395		glUseProgram(0);
396		glDeleteProgram(m_po);
397		glDeleteBuffers(1, &m_xfbo);
398		return NO_ERROR;
399	}
400
401	virtual long Run()
402	{
403		const char* const glsl_vs = "#version 430 core" NL "layout(location = 0) in vec4 vs_in_attrib[16];" NL
404									"out StageData {" NL "  vec4 attrib[16];" NL "} vs_out;" NL "void main() {" NL
405									"  for (int i = 0; i < vs_in_attrib.length(); ++i) {" NL
406									"    vs_out.attrib[i] = vs_in_attrib[i];" NL "  }" NL "}";
407		m_po = glCreateProgram();
408		{
409			const GLuint sh = glCreateShader(GL_VERTEX_SHADER);
410			glShaderSource(sh, 1, &glsl_vs, NULL);
411			glCompileShader(sh);
412			glAttachShader(m_po, sh);
413			glDeleteShader(sh);
414		}
415		{
416			const GLchar* const v[16] = { "StageData.attrib[0]",  "StageData.attrib[1]",  "StageData.attrib[2]",
417										  "StageData.attrib[3]",  "StageData.attrib[4]",  "StageData.attrib[5]",
418										  "StageData.attrib[6]",  "StageData.attrib[7]",  "StageData.attrib[8]",
419										  "StageData.attrib[9]",  "StageData.attrib[10]", "StageData.attrib[11]",
420										  "StageData.attrib[12]", "StageData.attrib[13]", "StageData.attrib[14]",
421										  "StageData.attrib[15]" };
422			glTransformFeedbackVaryings(m_po, 16, v, GL_INTERLEAVED_ATTRIBS);
423		}
424		glLinkProgram(m_po);
425		if (!CheckProgram(m_po))
426			return ERROR;
427
428		{
429			std::vector<GLubyte> zero(sizeof(expected_data));
430			glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_xfbo);
431			glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(expected_data), &zero[0], GL_DYNAMIC_DRAW);
432		}
433
434		glEnable(GL_RASTERIZER_DISCARD);
435		glUseProgram(m_po);
436		glBeginTransformFeedback(GL_POINTS);
437		if (base_instance != -1)
438		{
439			glDrawArraysInstancedBaseInstance(GL_POINTS, 0, 2, instance_count, static_cast<GLuint>(base_instance));
440		}
441		else
442		{
443			glDrawArraysInstanced(GL_POINTS, 0, 2, instance_count);
444		}
445		glEndTransformFeedback();
446
447		Vec4 data[64];
448		glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(Vec4) * 64, &data[0]);
449
450		long status = NO_ERROR;
451		for (int i = 0; i < 64; ++i)
452		{
453			if (!ColorEqual(expected_data[i], data[i], Vec4(0.01f)))
454			{
455				m_context.getTestContext().getLog()
456					<< tcu::TestLog::Message << "Data is: " << data[i][0] << " " << data[i][1] << " " << data[i][2]
457					<< " " << data[i][3] << ", data should be: " << expected_data[i][0] << " " << expected_data[i][1]
458					<< " " << expected_data[i][2] << " " << expected_data[i][3] << ", index is: " << i
459					<< tcu::TestLog::EndMessage;
460				status = ERROR;
461				break;
462			}
463		}
464		return status;
465	}
466};
467
468//=============================================================================
469// 1.2.1 BasicInputCase1
470//-----------------------------------------------------------------------------
471class BasicInputCase1 : public BasicInputBase
472{
473	GLuint m_vao, m_vbo;
474
475	virtual long Setup()
476	{
477		BasicInputBase::Setup();
478		glGenVertexArrays(1, &m_vao);
479		glGenBuffers(1, &m_vbo);
480		return NO_ERROR;
481	}
482
483	virtual long Cleanup()
484	{
485		BasicInputBase::Cleanup();
486		glDeleteVertexArrays(1, &m_vao);
487		glDeleteBuffers(1, &m_vbo);
488		return NO_ERROR;
489	}
490
491	virtual long Run()
492	{
493		for (GLuint i = 0; i < 16; ++i)
494		{
495			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
496		}
497		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
498		glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 2, NULL, GL_STATIC_DRAW);
499		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);
500		glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);
501		glBindBuffer(GL_ARRAY_BUFFER, 0);
502
503		glBindVertexArray(m_vao);
504		glBindVertexBuffer(0, m_vbo, 0, 12);
505		glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
506		glVertexAttribBinding(1, 0);
507		glEnableVertexAttribArray(1);
508
509		expected_data[1]  = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
510		expected_data[17] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
511		return BasicInputBase::Run();
512	}
513};
514
515//=============================================================================
516// 1.2.2 BasicInputCase2
517//-----------------------------------------------------------------------------
518class BasicInputCase2 : public BasicInputBase
519{
520	GLuint m_vao, m_vbo;
521
522	virtual long Setup()
523	{
524		BasicInputBase::Setup();
525		glGenVertexArrays(1, &m_vao);
526		glGenBuffers(1, &m_vbo);
527		return NO_ERROR;
528	}
529
530	virtual long Cleanup()
531	{
532		BasicInputBase::Cleanup();
533		glDeleteVertexArrays(1, &m_vao);
534		glDeleteBuffers(1, &m_vbo);
535		return NO_ERROR;
536	}
537
538	virtual long Run()
539	{
540		for (GLuint i = 0; i < 16; ++i)
541		{
542			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
543		}
544		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
545		glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 2, NULL, GL_STATIC_DRAW);
546		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);
547		glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);
548		glBindBuffer(GL_ARRAY_BUFFER, 0);
549
550		glBindVertexArray(m_vao);
551		glVertexAttribBinding(1, 0);
552		glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
553		glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
554		glVertexAttribFormat(7, 1, GL_FLOAT, GL_FALSE, 8);
555		glVertexAttribFormat(15, 2, GL_FLOAT, GL_FALSE, 4);
556		glVertexAttribBinding(0, 0);
557		glVertexAttribBinding(7, 0);
558		glVertexAttribBinding(15, 0);
559		glBindVertexBuffer(0, m_vbo, 0, 12);
560		glEnableVertexAttribArray(0);
561		glEnableVertexAttribArray(1);
562		glEnableVertexAttribArray(7);
563		glEnableVertexAttribArray(15);
564
565		expected_data[0]  = Vec4(1.0f, 2.0f, 0.0f, 1.0f);
566		expected_data[1]  = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
567		expected_data[7]  = Vec4(3.0f, 0.0f, 0.0f, 1.0f);
568		expected_data[15] = Vec4(2.0f, 3.0f, 0.0f, 1.0f);
569		expected_data[16] = Vec4(4.0f, 5.0f, 0.0f, 1.0f);
570		expected_data[17] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
571		expected_data[23] = Vec4(6.0f, 0.0f, 0.0f, 1.0f);
572		expected_data[31] = Vec4(5.0f, 6.0f, 0.0f, 1.0f);
573		return BasicInputBase::Run();
574	}
575};
576
577//=============================================================================
578// 1.2.3 BasicInputCase3
579//-----------------------------------------------------------------------------
580class BasicInputCase3 : public BasicInputBase
581{
582	GLuint m_vao, m_vbo;
583
584	virtual long Setup()
585	{
586		BasicInputBase::Setup();
587		glGenVertexArrays(1, &m_vao);
588		glGenBuffers(1, &m_vbo);
589		return NO_ERROR;
590	}
591
592	virtual long Cleanup()
593	{
594		BasicInputBase::Cleanup();
595		glDeleteVertexArrays(1, &m_vao);
596		glDeleteBuffers(1, &m_vbo);
597		return NO_ERROR;
598	}
599
600	virtual long Run()
601	{
602		for (GLuint i = 0; i < 16; ++i)
603		{
604			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
605		}
606		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
607		glBufferData(GL_ARRAY_BUFFER, 36 * 2, NULL, GL_STATIC_DRAW);
608		{
609			GLubyte d[] = { 1, 2, 3, 4 };
610			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
611		}
612		glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec3), &Vec3(5.0f, 6.0f, 7.0f)[0]);
613		glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(Vec2), &Vec2(8.0f, 9.0f)[0]);
614		{
615			GLubyte d[] = { 10, 11, 12, 13 };
616			glBufferSubData(GL_ARRAY_BUFFER, 0 + 36, sizeof(d), d);
617		}
618		glBufferSubData(GL_ARRAY_BUFFER, 16 + 36, sizeof(Vec3), &Vec3(14.0f, 15.0f, 16.0f)[0]);
619		glBufferSubData(GL_ARRAY_BUFFER, 28 + 36, sizeof(Vec2), &Vec2(17.0f, 18.0f)[0]);
620		glBindBuffer(GL_ARRAY_BUFFER, 0);
621
622		glBindVertexArray(m_vao);
623		glEnableVertexAttribArray(1);
624		glVertexAttribFormat(0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0);
625		glVertexAttribBinding(1, 3);
626		glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 16);
627		glVertexAttribBinding(2, 3);
628		glVertexAttribFormat(2, 2, GL_FLOAT, GL_FALSE, 28);
629		glVertexAttribBinding(0, 3);
630		glBindVertexBuffer(3, m_vbo, 0, 36);
631		glEnableVertexAttribArray(0);
632		glEnableVertexAttribArray(2);
633
634		expected_data[0]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
635		expected_data[1]	  = Vec4(5.0f, 6.0f, 7.0f, 1.0f);
636		expected_data[2]	  = Vec4(8.0f, 9.0f, 0.0f, 1.0f);
637		expected_data[0 + 16] = Vec4(10.0f, 11.0f, 12.0f, 13.0f);
638		expected_data[1 + 16] = Vec4(14.0f, 15.0f, 16.0f, 1.0f);
639		expected_data[2 + 16] = Vec4(17.0f, 18.0f, 0.0f, 1.0f);
640		return BasicInputBase::Run();
641	}
642};
643
644//=============================================================================
645// 1.2.4 BasicInputCase4
646//-----------------------------------------------------------------------------
647class BasicInputCase4 : public BasicInputBase
648{
649	GLuint m_vao, m_vbo[2];
650
651	virtual long Setup()
652	{
653		BasicInputBase::Setup();
654		glGenVertexArrays(1, &m_vao);
655		glGenBuffers(2, m_vbo);
656		return NO_ERROR;
657	}
658
659	virtual long Cleanup()
660	{
661		BasicInputBase::Cleanup();
662		glDeleteVertexArrays(1, &m_vao);
663		glDeleteBuffers(2, m_vbo);
664		return NO_ERROR;
665	}
666
667	virtual long Run()
668	{
669		for (GLuint i = 0; i < 16; ++i)
670		{
671			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
672		}
673		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
674		glBufferData(GL_ARRAY_BUFFER, 20 * 2, NULL, GL_STATIC_DRAW);
675		{
676			GLbyte d[] = { -127, 127, -127, 127 };
677			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
678		}
679		{
680			GLushort d[] = { 1, 2, 3, 4 };
681			glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);
682		}
683		{
684			GLuint d[] = { 5, 6 };
685			glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);
686		}
687		{
688			GLbyte d[] = { 127, -127, 127, -127 };
689			glBufferSubData(GL_ARRAY_BUFFER, 0 + 20, sizeof(d), d);
690		}
691		{
692			GLushort d[] = { 7, 8, 9, 10 };
693			glBufferSubData(GL_ARRAY_BUFFER, 4 + 20, sizeof(d), d);
694		}
695		{
696			GLuint d[] = { 11, 12 };
697			glBufferSubData(GL_ARRAY_BUFFER, 12 + 20, sizeof(d), d);
698		}
699		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
700		glBufferData(GL_ARRAY_BUFFER, 24 * 2 + 8, NULL, GL_STATIC_DRAW);
701		{
702			GLdouble d[] = { 0.0, 100.0, 200.0 };
703			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
704		}
705		{
706			GLdouble d[] = { 300.0, 400.0 };
707			glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);
708		}
709		glBindBuffer(GL_ARRAY_BUFFER, 0);
710
711		glBindVertexArray(m_vao);
712		glVertexAttribFormat(0, 4, GL_BYTE, GL_TRUE, 0);
713		glVertexAttribFormat(1, 4, GL_UNSIGNED_SHORT, GL_FALSE, 4);
714		glVertexAttribFormat(2, 2, GL_UNSIGNED_INT, GL_FALSE, 12);
715		glVertexAttribFormat(5, 2, GL_DOUBLE, GL_FALSE, 0);
716		glVertexAttribBinding(0, 0);
717		glVertexAttribBinding(1, 0);
718		glVertexAttribBinding(2, 0);
719		glVertexAttribBinding(5, 6);
720		glBindVertexBuffer(0, m_vbo[0], 0, 20);
721		glBindVertexBuffer(6, m_vbo[1], 8, 24);
722		glEnableVertexAttribArray(0);
723		glEnableVertexAttribArray(1);
724		glEnableVertexAttribArray(2);
725		glEnableVertexAttribArray(5);
726
727		expected_data[0]	  = Vec4(-1.0f, 1.0f, -1.0f, 1.0f);
728		expected_data[1]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
729		expected_data[2]	  = Vec4(5.0f, 6.0f, 0.0f, 1.0f);
730		expected_data[5]	  = Vec4(100.0f, 200.0f, 0.0f, 1.0f);
731		expected_data[0 + 16] = Vec4(1.0f, -1.0f, 1.0f, -1.0f);
732		expected_data[1 + 16] = Vec4(7.0f, 8.0f, 9.0f, 10.0f);
733		expected_data[2 + 16] = Vec4(11.0f, 12.0f, 0.0f, 1.0f);
734		expected_data[5 + 16] = Vec4(300.0f, 400.0f, 0.0f, 1.0f);
735		return BasicInputBase::Run();
736	}
737};
738
739//=============================================================================
740// 1.2.5 BasicInputCase5
741//-----------------------------------------------------------------------------
742class BasicInputCase5 : public BasicInputBase
743{
744	GLuint m_vao, m_vbo;
745
746	virtual long Setup()
747	{
748		BasicInputBase::Setup();
749		glGenVertexArrays(1, &m_vao);
750		glGenBuffers(1, &m_vbo);
751		return NO_ERROR;
752	}
753
754	virtual long Cleanup()
755	{
756		BasicInputBase::Cleanup();
757		glDeleteVertexArrays(1, &m_vao);
758		glDeleteBuffers(1, &m_vbo);
759		return NO_ERROR;
760	}
761
762	virtual long Run()
763	{
764		for (GLuint i = 0; i < 16; ++i)
765		{
766			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
767		}
768		const int kStride = 116;
769		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
770		glBufferData(GL_ARRAY_BUFFER, kStride * 2, NULL, GL_STATIC_DRAW);
771		{
772			GLubyte d[] = { 0, 0xff, 0xff / 2, 0 };
773			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
774		}
775		{
776			GLushort d[] = { 0, 0xffff, 0xffff / 2, 0 };
777			glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);
778		}
779		{
780			GLuint d[] = { 0, 0xffffffff, 0xffffffff / 2, 0 };
781			glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);
782		}
783		{
784			GLbyte d[] = { 0, -127, 127, 0 };
785			glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(d), d);
786		}
787		{
788			GLshort d[] = { 0, -32767, 32767, 0 };
789			glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);
790		}
791		{
792			GLint d[] = { 0, -2147483647, 2147483647, 0 };
793			glBufferSubData(GL_ARRAY_BUFFER, 40, sizeof(d), d);
794		}
795		{
796			GLfloat d[] = { 0, 1.0f, 2.0f, 0 };
797			glBufferSubData(GL_ARRAY_BUFFER, 56, sizeof(d), d);
798		}
799		{
800			GLdouble d[] = { 0, 10.0, 20.0, 0 };
801			glBufferSubData(GL_ARRAY_BUFFER, 72, sizeof(d), d);
802		}
803		{
804			GLubyte d[] = { 0, 0xff / 4, 0xff / 2, 0xff };
805			glBufferSubData(GL_ARRAY_BUFFER, 104, sizeof(d), d);
806		}
807		{
808			GLuint d = 0 | (1023 << 10) | (511 << 20) | (1 << 30);
809			glBufferSubData(GL_ARRAY_BUFFER, 108, sizeof(d), &d);
810		}
811		{
812			GLint d = 0 | (511 << 10) | (255 << 20) | (0 << 30);
813			glBufferSubData(GL_ARRAY_BUFFER, 112, sizeof(d), &d);
814		}
815
816		{
817			GLubyte d[] = { 0xff, 0xff, 0xff / 2, 0 };
818			glBufferSubData(GL_ARRAY_BUFFER, 0 + kStride, sizeof(d), d);
819		}
820		{
821			GLushort d[] = { 0xffff, 0xffff, 0xffff / 2, 0 };
822			glBufferSubData(GL_ARRAY_BUFFER, 4 + kStride, sizeof(d), d);
823		}
824		{
825			GLuint d[] = { 0xffffffff, 0xffffffff, 0xffffffff / 2, 0 };
826			glBufferSubData(GL_ARRAY_BUFFER, 12 + kStride, sizeof(d), d);
827		}
828		{
829			GLbyte d[] = { 127, -127, 127, 0 };
830			glBufferSubData(GL_ARRAY_BUFFER, 28 + kStride, sizeof(d), d);
831		}
832		{
833			GLshort d[] = { 32767, -32767, 32767, 0 };
834			glBufferSubData(GL_ARRAY_BUFFER, 32 + kStride, sizeof(d), d);
835		}
836		{
837			GLint d[] = { 2147483647, -2147483647, 2147483647, 0 };
838			glBufferSubData(GL_ARRAY_BUFFER, 40 + kStride, sizeof(d), d);
839		}
840		{
841			GLfloat d[] = { 0, 3.0f, 4.0f, 0 };
842			glBufferSubData(GL_ARRAY_BUFFER, 56 + kStride, sizeof(d), d);
843		}
844		{
845			GLdouble d[] = { 0, 30.0, 40.0, 0 };
846			glBufferSubData(GL_ARRAY_BUFFER, 72 + kStride, sizeof(d), d);
847		}
848		{
849			GLubyte d[] = { 0xff, 0xff / 2, 0xff / 4, 0 };
850			glBufferSubData(GL_ARRAY_BUFFER, 104 + kStride, sizeof(d), d);
851		}
852		{
853			GLuint d = 0 | (1023 << 10) | (511 << 20) | (2u << 30);
854			glBufferSubData(GL_ARRAY_BUFFER, 108 + kStride, sizeof(d), &d);
855		}
856		{
857			GLint d = (-511 & 0x3ff) | (511 << 10) | (255 << 20) | 3 << 30;
858			glBufferSubData(GL_ARRAY_BUFFER, 112 + kStride, sizeof(d), &d);
859		}
860		glBindBuffer(GL_ARRAY_BUFFER, 0);
861
862		glBindVertexArray(m_vao);
863		glVertexAttribFormat(0, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0);
864		glVertexAttribFormat(1, 4, GL_UNSIGNED_SHORT, GL_TRUE, 4);
865		glVertexAttribFormat(2, 4, GL_UNSIGNED_INT, GL_TRUE, 12);
866		glVertexAttribFormat(3, 4, GL_BYTE, GL_TRUE, 28);
867		glVertexAttribFormat(4, 4, GL_SHORT, GL_TRUE, 32);
868		glVertexAttribFormat(5, 4, GL_INT, GL_TRUE, 40);
869		glVertexAttribFormat(6, 4, GL_FLOAT, GL_TRUE, 56);
870		glVertexAttribFormat(7, 4, GL_DOUBLE, GL_TRUE, 72);
871		glVertexAttribFormat(8, GL_BGRA, GL_UNSIGNED_BYTE, GL_TRUE, 104);
872		glVertexAttribFormat(9, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 108);
873		glVertexAttribFormat(10, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 108);
874		glVertexAttribFormat(11, 4, GL_INT_2_10_10_10_REV, GL_TRUE, 112);
875		glVertexAttribFormat(12, GL_BGRA, GL_INT_2_10_10_10_REV, GL_TRUE, 112);
876
877		for (GLuint i = 0; i < 13; ++i)
878		{
879			glVertexAttribBinding(i, 0);
880			glEnableVertexAttribArray(i);
881		}
882		glBindVertexBuffer(0, m_vbo, 0, kStride);
883
884		expected_data[0]	   = Vec4(0.0f, 1.0f, 0.5f, 0.0f);
885		expected_data[1]	   = Vec4(0.0f, 1.0f, 0.5f, 0.0f);
886		expected_data[2]	   = Vec4(0.0f, 1.0f, 0.5f, 0.0f);
887		expected_data[3]	   = Vec4(0.0f, -1.0f, 1.0f, 0.0f);
888		expected_data[4]	   = Vec4(0.0f, -1.0f, 1.0f, 0.0f);
889		expected_data[5]	   = Vec4(0.0f, -1.0f, 1.0f, 0.0f);
890		expected_data[6]	   = Vec4(0.0f, 1.0f, 2.0f, 0.0f);
891		expected_data[7]	   = Vec4(0.0f, 10.0f, 20.0f, 0.0f);
892		expected_data[8]	   = Vec4(0.5f, 0.25f, 0.0f, 1.0f);
893		expected_data[9]	   = Vec4(0.0f, 1.0f, 0.5f, 0.33f);
894		expected_data[10]	  = Vec4(0.5f, 1.0f, 0.0f, 0.33f);
895		expected_data[11]	  = Vec4(0.0f, 1.0f, 0.5f, 0.0f);
896		expected_data[12]	  = Vec4(0.5f, 1.0f, 0.0f, 0.0f);
897		expected_data[0 + 16]  = Vec4(1.0f, 1.0f, 0.5f, 0.0f);
898		expected_data[1 + 16]  = Vec4(1.0f, 1.0f, 0.5f, 0.0f);
899		expected_data[2 + 16]  = Vec4(1.0f, 1.0f, 0.5f, 0.0f);
900		expected_data[3 + 16]  = Vec4(1.0f, -1.0f, 1.0f, 0.0f);
901		expected_data[4 + 16]  = Vec4(1.0f, -1.0f, 1.0f, 0.0f);
902		expected_data[5 + 16]  = Vec4(1.0f, -1.0f, 1.0f, 0.0f);
903		expected_data[6 + 16]  = Vec4(0.0f, 3.0f, 4.0f, 0.0f);
904		expected_data[7 + 16]  = Vec4(0.0f, 30.0f, 40.0f, 0.0f);
905		expected_data[8 + 16]  = Vec4(0.25f, 0.5f, 1.0f, 0.0f);
906		expected_data[9 + 16]  = Vec4(0.0f, 1.0f, 0.5f, 0.66f);
907		expected_data[10 + 16] = Vec4(0.5f, 1.0f, 0.0f, 0.66f);
908		expected_data[11 + 16] = Vec4(-1.0f, 1.0f, 0.5f, -1.0f);
909		expected_data[12 + 16] = Vec4(0.5f, 1.0f, -1.0f, -1.0f);
910		return BasicInputBase::Run();
911	}
912};
913
914//=============================================================================
915// 1.2.6 BasicInputCase6
916//-----------------------------------------------------------------------------
917class BasicInputCase6 : public BasicInputBase
918{
919	GLuint m_vao, m_vbo;
920
921	virtual long Setup()
922	{
923		BasicInputBase::Setup();
924		glGenVertexArrays(1, &m_vao);
925		glGenBuffers(1, &m_vbo);
926		return NO_ERROR;
927	}
928
929	virtual long Cleanup()
930	{
931		BasicInputBase::Cleanup();
932		glDeleteVertexArrays(1, &m_vao);
933		glDeleteBuffers(1, &m_vbo);
934		return NO_ERROR;
935	}
936
937	virtual long Run()
938	{
939		for (GLuint i = 0; i < 16; ++i)
940		{
941			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
942		}
943		const int kStride = 112;
944		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
945		glBufferData(GL_ARRAY_BUFFER, kStride * 2, NULL, GL_STATIC_DRAW);
946		{
947			GLubyte d[] = { 1, 2, 3, 4 };
948			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
949		}
950		{
951			GLushort d[] = { 5, 6, 7, 8 };
952			glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);
953		}
954		{
955			GLuint d[] = { 9, 10, 11, 12 };
956			glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);
957		}
958		{
959			GLbyte d[] = { -1, 2, -3, 4 };
960			glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(d), d);
961		}
962		{
963			GLshort d[] = { -5, 6, -7, 8 };
964			glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);
965		}
966		{
967			GLint d[] = { -9, 10, -11, 12 };
968			glBufferSubData(GL_ARRAY_BUFFER, 40, sizeof(d), d);
969		}
970		{
971			GLfloat d[] = { -13.0f, 14.0f, -15.0f, 16.0f };
972			glBufferSubData(GL_ARRAY_BUFFER, 56, sizeof(d), d);
973		}
974		{
975			GLdouble d[] = { -18.0, 19.0, -20.0, 21.0 };
976			glBufferSubData(GL_ARRAY_BUFFER, 72, sizeof(d), d);
977		}
978		{
979			GLuint d = 0 | (11 << 10) | (12 << 20) | (2u << 30);
980			glBufferSubData(GL_ARRAY_BUFFER, 104, sizeof(d), &d);
981		}
982		{
983			GLint d = 0 | ((0xFFFFFFF5 << 10) & (0x3ff << 10)) | (12 << 20) | (1 << 30);
984			glBufferSubData(GL_ARRAY_BUFFER, 108, sizeof(d), &d);
985		}
986		{
987			GLubyte d[] = { 22, 23, 24, 25 };
988			glBufferSubData(GL_ARRAY_BUFFER, 0 + kStride, sizeof(d), d);
989		}
990		{
991			GLushort d[] = { 26, 27, 28, 29 };
992			glBufferSubData(GL_ARRAY_BUFFER, 4 + kStride, sizeof(d), d);
993		}
994		{
995			GLuint d[] = { 30, 31, 32, 33 };
996			glBufferSubData(GL_ARRAY_BUFFER, 12 + kStride, sizeof(d), d);
997		}
998		{
999			GLbyte d[] = { -34, 35, -36, 37 };
1000			glBufferSubData(GL_ARRAY_BUFFER, 28 + kStride, sizeof(d), d);
1001		}
1002		{
1003			GLshort d[] = { -38, 39, -40, 41 };
1004			glBufferSubData(GL_ARRAY_BUFFER, 32 + kStride, sizeof(d), d);
1005		}
1006		{
1007			GLint d[] = { -42, 43, -44, 45 };
1008			glBufferSubData(GL_ARRAY_BUFFER, 40 + kStride, sizeof(d), d);
1009		}
1010		{
1011			GLfloat d[] = { -46.0f, 47.0f, -48.0f, 49.0f };
1012			glBufferSubData(GL_ARRAY_BUFFER, 56 + kStride, sizeof(d), d);
1013		}
1014		{
1015			GLdouble d[] = { -50.0, 51.0, -52.0, 53.0 };
1016			glBufferSubData(GL_ARRAY_BUFFER, 72 + kStride, sizeof(d), d);
1017		}
1018		{
1019			GLuint d = 0 | (11 << 10) | (12 << 20) | (1 << 30);
1020			glBufferSubData(GL_ARRAY_BUFFER, 104 + kStride, sizeof(d), &d);
1021		}
1022		{
1023			GLint d = 123 | ((0xFFFFFFFD << 10) & (0x3ff << 10)) | ((0xFFFFFE0C << 20) & (0x3ff << 20)) |
1024					  ((0xFFFFFFFF << 30) & (0x3 << 30));
1025			glBufferSubData(GL_ARRAY_BUFFER, 108 + kStride, sizeof(d), &d);
1026		}
1027		glBindBuffer(GL_ARRAY_BUFFER, 0);
1028
1029		glBindVertexArray(m_vao);
1030		glVertexAttribFormat(0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0);
1031		glVertexAttribFormat(1, 4, GL_UNSIGNED_SHORT, GL_FALSE, 4);
1032		glVertexAttribFormat(2, 4, GL_UNSIGNED_INT, GL_FALSE, 12);
1033		glVertexAttribFormat(3, 4, GL_BYTE, GL_FALSE, 28);
1034		glVertexAttribFormat(4, 4, GL_SHORT, GL_FALSE, 32);
1035		glVertexAttribFormat(5, 4, GL_INT, GL_FALSE, 40);
1036		glVertexAttribFormat(6, 4, GL_FLOAT, GL_FALSE, 56);
1037		glVertexAttribFormat(7, 4, GL_DOUBLE, GL_FALSE, 72);
1038		glVertexAttribFormat(8, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 104);
1039		glVertexAttribFormat(9, 4, GL_INT_2_10_10_10_REV, GL_FALSE, 108);
1040		for (GLuint i = 0; i < 10; ++i)
1041		{
1042			glVertexAttribBinding(i, 0);
1043			glEnableVertexAttribArray(i);
1044		}
1045		glBindVertexBuffer(0, m_vbo, 0, kStride);
1046
1047		expected_data[0]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1048		expected_data[1]	  = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1049		expected_data[2]	  = Vec4(9.0f, 10.0f, 11.0f, 12.0f);
1050		expected_data[3]	  = Vec4(-1.0f, 2.0f, -3.0f, 4.0f);
1051		expected_data[4]	  = Vec4(-5.0f, 6.0f, -7.0f, 8.0f);
1052		expected_data[5]	  = Vec4(-9.0f, 10.0f, -11.0f, 12.0f);
1053		expected_data[6]	  = Vec4(-13.0f, 14.0f, -15.0f, 16.0f);
1054		expected_data[7]	  = Vec4(-18.0f, 19.0f, -20.0f, 21.0f);
1055		expected_data[8]	  = Vec4(0.0f, 11.0f, 12.0f, 2.0f);
1056		expected_data[9]	  = Vec4(0.0f, -11.0f, 12.0f, 1.0f);
1057		expected_data[0 + 16] = Vec4(22.0f, 23.0f, 24.0f, 25.0f);
1058		expected_data[1 + 16] = Vec4(26.0f, 27.0f, 28.0f, 29.0f);
1059		expected_data[2 + 16] = Vec4(30.0f, 31.0f, 32.0f, 33.0f);
1060		expected_data[3 + 16] = Vec4(-34.0f, 35.0f, -36.0f, 37.0f);
1061		expected_data[4 + 16] = Vec4(-38.0f, 39.0f, -40.0f, 41.0f);
1062		expected_data[5 + 16] = Vec4(-42.0f, 43.0f, -44.0f, 45.0f);
1063		expected_data[6 + 16] = Vec4(-46.0f, 47.0f, -48.0f, 49.0f);
1064		expected_data[7 + 16] = Vec4(-50.0f, 51.0f, -52.0f, 53.0f);
1065		expected_data[8 + 16] = Vec4(0.0f, 11.0f, 12.0f, 1.0f);
1066		expected_data[9 + 16] = Vec4(123.0f, -3.0f, -500.0f, -1.0f);
1067		return BasicInputBase::Run();
1068	}
1069};
1070
1071//=============================================================================
1072// 1.2.7 BasicInputCase7
1073//-----------------------------------------------------------------------------
1074class BasicInputCase7 : public BasicInputBase
1075{
1076	GLuint m_vao, m_vbo[2];
1077
1078	virtual long Setup()
1079	{
1080		BasicInputBase::Setup();
1081		glGenVertexArrays(1, &m_vao);
1082		glGenBuffers(2, m_vbo);
1083		return NO_ERROR;
1084	}
1085
1086	virtual long Cleanup()
1087	{
1088		BasicInputBase::Cleanup();
1089		glDeleteVertexArrays(1, &m_vao);
1090		glDeleteBuffers(2, m_vbo);
1091		return NO_ERROR;
1092	}
1093
1094	virtual long Run()
1095	{
1096		for (GLuint i = 0; i < 16; ++i)
1097		{
1098			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
1099		}
1100		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
1101		glBufferData(GL_ARRAY_BUFFER, 6 * 4, NULL, GL_STATIC_DRAW);
1102		{
1103			GLfloat d[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f };
1104			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
1105		}
1106
1107		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
1108		glBufferData(GL_ARRAY_BUFFER, 10 * 4, NULL, GL_STATIC_DRAW);
1109		{
1110			GLfloat d[] = { -1.0f, -2.0f, -3.0f, -4.0f, -5.0f, -6.0f, -7.0f, -8.0f, -9.0f, -10.0f };
1111			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
1112		}
1113		glBindBuffer(GL_ARRAY_BUFFER, 0);
1114
1115		glBindVertexArray(m_vao);
1116		glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
1117		glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
1118		glVertexAttribFormat(2, 1, GL_FLOAT, GL_FALSE, 4);
1119		glVertexAttribFormat(5, 4, GL_FLOAT, GL_FALSE, 12);
1120		glVertexAttribFormat(14, 2, GL_FLOAT, GL_FALSE, 8);
1121		glVertexAttribBinding(0, 0);
1122		glVertexAttribBinding(1, 1);
1123		glVertexAttribBinding(2, 1);
1124		glVertexAttribBinding(5, 15);
1125		glVertexAttribBinding(14, 7);
1126		glBindVertexBuffer(0, m_vbo[0], 0, 12);
1127		glBindVertexBuffer(1, m_vbo[0], 4, 4);
1128		glBindVertexBuffer(7, m_vbo[1], 8, 16);
1129		glBindVertexBuffer(15, m_vbo[1], 12, 0);
1130		glEnableVertexAttribArray(0);
1131		glEnableVertexAttribArray(1);
1132		glEnableVertexAttribArray(2);
1133		glEnableVertexAttribArray(5);
1134		glEnableVertexAttribArray(14);
1135
1136		base_instance		   = 0;
1137		expected_data[0]	   = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
1138		expected_data[1]	   = Vec4(2.0f, 3.0f, 4.0f, 1.0f);
1139		expected_data[2]	   = Vec4(3.0f, 0.0f, 0.0f, 1.0f);
1140		expected_data[5]	   = Vec4(-7.0f, -8.0f, -9.0f, -10.0f);
1141		expected_data[14]	  = Vec4(-5.0f, -6.0f, 0.0f, 1.0f);
1142		expected_data[0 + 16]  = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
1143		expected_data[1 + 16]  = Vec4(3.0f, 4.0f, 5.0f, 1.0f);
1144		expected_data[2 + 16]  = Vec4(4.0f, 0.0f, 0.0f, 1.0f);
1145		expected_data[5 + 16]  = Vec4(-7.0f, -8.0f, -9.0f, -10.0f);
1146		expected_data[14 + 16] = Vec4(-9.0f, -10.0f, 0.0f, 1.0f);
1147		return BasicInputBase::Run();
1148	}
1149};
1150
1151//=============================================================================
1152// 1.2.8 BasicInputCase8
1153//-----------------------------------------------------------------------------
1154class BasicInputCase8 : public BasicInputBase
1155{
1156	GLuint m_vao, m_vbo[2];
1157
1158	virtual long Setup()
1159	{
1160		BasicInputBase::Setup();
1161		glGenVertexArrays(1, &m_vao);
1162		glGenBuffers(2, m_vbo);
1163		return NO_ERROR;
1164	}
1165
1166	virtual long Cleanup()
1167	{
1168		BasicInputBase::Cleanup();
1169		glDeleteVertexArrays(1, &m_vao);
1170		glDeleteBuffers(2, m_vbo);
1171		return NO_ERROR;
1172	}
1173
1174	virtual long Run()
1175	{
1176		for (GLuint i = 0; i < 16; ++i)
1177		{
1178			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
1179		}
1180		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
1181		glBufferData(GL_ARRAY_BUFFER, 6 * 4, NULL, GL_STATIC_DRAW);
1182		{
1183			GLfloat d[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f };
1184			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
1185		}
1186
1187		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
1188		glBufferData(GL_ARRAY_BUFFER, 10 * 4, NULL, GL_STATIC_DRAW);
1189		{
1190			GLfloat d[] = { -1.0f, -2.0f, -3.0f, -4.0f, -5.0f, -6.0f, -7.0f, -8.0f, -9.0f, -10.0f };
1191			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
1192		}
1193		glBindBuffer(GL_ARRAY_BUFFER, 0);
1194
1195		glBindVertexArray(m_vao);
1196		glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
1197		glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
1198		glVertexAttribFormat(2, 1, GL_FLOAT, GL_FALSE, 4);
1199		glVertexAttribFormat(5, 4, GL_FLOAT, GL_FALSE, 12);
1200		glVertexAttribFormat(14, 2, GL_FLOAT, GL_FALSE, 8);
1201		glVertexAttribBinding(0, 0);
1202		glVertexAttribBinding(1, 1);
1203		glVertexAttribBinding(2, 1);
1204		glVertexAttribBinding(5, 15);
1205		glVertexAttribBinding(14, 7);
1206		glBindVertexBuffer(0, m_vbo[0], 0, 12);
1207		glBindVertexBuffer(1, m_vbo[0], 4, 4);
1208		glBindVertexBuffer(7, m_vbo[1], 8, 16);
1209		glBindVertexBuffer(15, m_vbo[1], 12, 0);
1210		glEnableVertexAttribArray(0);
1211		glEnableVertexAttribArray(1);
1212		glEnableVertexAttribArray(2);
1213		glEnableVertexAttribArray(5);
1214		glEnableVertexAttribArray(14);
1215
1216		expected_data[0]	   = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
1217		expected_data[1]	   = Vec4(2.0f, 3.0f, 4.0f, 1.0f);
1218		expected_data[2]	   = Vec4(3.0f, 0.0f, 0.0f, 1.0f);
1219		expected_data[5]	   = Vec4(-7.0f, -8.0f, -9.0f, -10.0f);
1220		expected_data[14]	  = Vec4(-5.0f, -6.0f, 0.0f, 1.0f);
1221		expected_data[0 + 16]  = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
1222		expected_data[1 + 16]  = Vec4(3.0f, 4.0f, 5.0f, 1.0f);
1223		expected_data[2 + 16]  = Vec4(4.0f, 0.0f, 0.0f, 1.0f);
1224		expected_data[5 + 16]  = Vec4(-7.0f, -8.0f, -9.0f, -10.0f);
1225		expected_data[14 + 16] = Vec4(-9.0f, -10.0f, 0.0f, 1.0f);
1226		return BasicInputBase::Run();
1227	}
1228};
1229
1230//=============================================================================
1231// 1.2.9 BasicInputCase9
1232//-----------------------------------------------------------------------------
1233class BasicInputCase9 : public BasicInputBase
1234{
1235	GLuint m_vao, m_vbo[2];
1236
1237	virtual long Setup()
1238	{
1239		BasicInputBase::Setup();
1240		glGenVertexArrays(1, &m_vao);
1241		glGenBuffers(2, m_vbo);
1242		return NO_ERROR;
1243	}
1244
1245	virtual long Cleanup()
1246	{
1247		BasicInputBase::Cleanup();
1248		glDeleteVertexArrays(1, &m_vao);
1249		glDeleteBuffers(2, m_vbo);
1250		return NO_ERROR;
1251	}
1252
1253	virtual long Run()
1254	{
1255		for (GLuint i = 0; i < 16; ++i)
1256		{
1257			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
1258		}
1259		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
1260		glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);
1261		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(1.0f, 2.0f, 3.0f, 4.0f)[0]);
1262		glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(5.0f, 6.0f, 7.0f, 8.0f)[0]);
1263		glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(Vec4), &Vec4(9.0f, 10.0f, 11.0f, 12.0f)[0]);
1264		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
1265		glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);
1266		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(10.0f, 20.0f, 30.0f, 40.0f)[0]);
1267		glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(50.0f, 60.0f, 70.0f, 80.0f)[0]);
1268		glBindBuffer(GL_ARRAY_BUFFER, 0);
1269
1270		glBindVertexArray(m_vao);
1271		glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, 0);
1272		glVertexAttribFormat(2, 4, GL_FLOAT, GL_FALSE, 0);
1273		glVertexAttribFormat(4, 2, GL_FLOAT, GL_FALSE, 4);
1274		glVertexAttribBinding(0, 0);
1275		glVertexAttribBinding(2, 1);
1276		glVertexAttribBinding(4, 3);
1277		glEnableVertexAttribArray(0);
1278		glEnableVertexAttribArray(2);
1279		glEnableVertexAttribArray(4);
1280		glBindVertexBuffer(0, m_vbo[0], 0, 16);
1281		glBindVertexBuffer(1, m_vbo[0], 0, 16);
1282		glBindVertexBuffer(3, m_vbo[1], 4, 8);
1283		glVertexBindingDivisor(1, 1);
1284
1285		instance_count		  = 2;
1286		base_instance		  = 0;
1287		expected_data[0]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1288		expected_data[2]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1289		expected_data[4]	  = Vec4(30.0f, 40.0f, 0.0f, 1.0f);
1290		expected_data[0 + 16] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1291		expected_data[2 + 16] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1292		expected_data[4 + 16] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);
1293
1294		expected_data[0 + 32]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1295		expected_data[2 + 32]	  = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1296		expected_data[4 + 32]	  = Vec4(30.0f, 40.0f, 0.0f, 1.0f);
1297		expected_data[0 + 16 + 32] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1298		expected_data[2 + 16 + 32] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1299		expected_data[4 + 16 + 32] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);
1300		return BasicInputBase::Run();
1301	}
1302};
1303
1304//=============================================================================
1305// 1.2.10 BasicInputCase10
1306//-----------------------------------------------------------------------------
1307class BasicInputCase10 : public BasicInputBase
1308{
1309	GLuint m_vao, m_vbo;
1310
1311	virtual long Setup()
1312	{
1313		BasicInputBase::Setup();
1314		glGenVertexArrays(1, &m_vao);
1315		glGenBuffers(1, &m_vbo);
1316		return NO_ERROR;
1317	}
1318
1319	virtual long Cleanup()
1320	{
1321		BasicInputBase::Cleanup();
1322		glDeleteVertexArrays(1, &m_vao);
1323		glDeleteBuffers(1, &m_vbo);
1324		return NO_ERROR;
1325	}
1326
1327	virtual long Run()
1328	{
1329		for (GLuint i = 0; i < 16; ++i)
1330		{
1331			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
1332		}
1333		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1334		glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 3, NULL, GL_STATIC_DRAW);
1335		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);
1336		glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);
1337		glBufferSubData(GL_ARRAY_BUFFER, 24, sizeof(Vec3), &Vec3(7.0f, 8.0f, 9.0f)[0]);
1338		glBindBuffer(GL_ARRAY_BUFFER, 0);
1339
1340		glBindVertexArray(m_vao);
1341		glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
1342		glVertexAttribFormat(2, 2, GL_FLOAT, GL_FALSE, 4);
1343		glVertexAttribBinding(0, 0);
1344		glVertexAttribBinding(2, 3);
1345		glBindVertexBuffer(0, m_vbo, 0, 12);
1346		glBindVertexBuffer(3, m_vbo, 4, 8);
1347		glEnableVertexAttribArray(0);
1348		glEnableVertexAttribArray(2);
1349		glVertexBindingDivisor(0, 1);
1350		glVertexBindingDivisor(3, 0);
1351
1352		instance_count		  = 2;
1353		base_instance		  = 1;
1354		expected_data[0]	  = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
1355		expected_data[2]	  = Vec4(3.0f, 4.0f, 0.0f, 1.0f);
1356		expected_data[0 + 16] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
1357		expected_data[2 + 16] = Vec4(5.0f, 6.0f, 0.0f, 1.0f);
1358
1359		expected_data[0 + 32]	  = Vec4(7.0f, 8.0f, 9.0f, 1.0f);
1360		expected_data[2 + 32]	  = Vec4(3.0f, 4.0f, 0.0f, 1.0f);
1361		expected_data[0 + 16 + 32] = Vec4(7.0f, 8.0f, 9.0f, 1.0f);
1362		expected_data[2 + 16 + 32] = Vec4(5.0f, 6.0f, 0.0f, 1.0f);
1363		return BasicInputBase::Run();
1364	}
1365};
1366
1367//=============================================================================
1368// 1.2.11 BasicInputCase11
1369//-----------------------------------------------------------------------------
1370class BasicInputCase11 : public BasicInputBase
1371{
1372	GLuint m_vao, m_vbo[2];
1373
1374	virtual long Setup()
1375	{
1376		BasicInputBase::Setup();
1377		glGenVertexArrays(1, &m_vao);
1378		glGenBuffers(2, m_vbo);
1379		return NO_ERROR;
1380	}
1381
1382	virtual long Cleanup()
1383	{
1384		BasicInputBase::Cleanup();
1385		glDeleteVertexArrays(1, &m_vao);
1386		glDeleteBuffers(2, m_vbo);
1387		return NO_ERROR;
1388	}
1389
1390	virtual long Run()
1391	{
1392		for (GLuint i = 0; i < 16; ++i)
1393		{
1394			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
1395		}
1396		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
1397		glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);
1398		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(1.0f, 2.0f, 3.0f, 4.0f)[0]);
1399		glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(5.0f, 6.0f, 7.0f, 8.0f)[0]);
1400		glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(Vec4), &Vec4(9.0f, 10.0f, 11.0f, 12.0f)[0]);
1401		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
1402		glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);
1403		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(10.0f, 20.0f, 30.0f, 40.0f)[0]);
1404		glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(50.0f, 60.0f, 70.0f, 80.0f)[0]);
1405		glBindBuffer(GL_ARRAY_BUFFER, 0);
1406
1407		glBindVertexArray(m_vao);
1408		glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, 0);
1409		glVertexAttribFormat(2, 4, GL_FLOAT, GL_FALSE, 0);
1410		glVertexAttribFormat(4, 2, GL_FLOAT, GL_FALSE, 4);
1411		glVertexAttribBinding(0, 0);
1412		glVertexAttribBinding(2, 1);
1413		glVertexAttribBinding(4, 2);
1414		glEnableVertexAttribArray(0);
1415		glEnableVertexAttribArray(2);
1416		glEnableVertexAttribArray(4);
1417		glBindVertexBuffer(0, m_vbo[0], 0, 16);
1418		glBindVertexBuffer(1, m_vbo[0], 0, 16);
1419		glBindVertexBuffer(2, m_vbo[1], 4, 8);
1420		glVertexBindingDivisor(1, 1);
1421
1422		instance_count		  = 2;
1423		expected_data[0]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1424		expected_data[2]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1425		expected_data[4]	  = Vec4(30.0f, 40.0f, 0.0f, 1.0f);
1426		expected_data[0 + 16] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1427		expected_data[2 + 16] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1428		expected_data[4 + 16] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);
1429
1430		expected_data[0 + 32]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1431		expected_data[2 + 32]	  = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1432		expected_data[4 + 32]	  = Vec4(30.0f, 40.0f, 0.0f, 1.0f);
1433		expected_data[0 + 16 + 32] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1434		expected_data[2 + 16 + 32] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1435		expected_data[4 + 16 + 32] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);
1436		return BasicInputBase::Run();
1437	}
1438};
1439
1440//=============================================================================
1441// 1.2.12 BasicInputCase12
1442//-----------------------------------------------------------------------------
1443class BasicInputCase12 : public BasicInputBase
1444{
1445	GLuint m_vao, m_vbo;
1446
1447	virtual long Setup()
1448	{
1449		BasicInputBase::Setup();
1450		glGenVertexArrays(1, &m_vao);
1451		glGenBuffers(1, &m_vbo);
1452		return NO_ERROR;
1453	}
1454
1455	virtual long Cleanup()
1456	{
1457		BasicInputBase::Cleanup();
1458		glDeleteVertexArrays(1, &m_vao);
1459		glDeleteBuffers(1, &m_vbo);
1460		return NO_ERROR;
1461	}
1462
1463	virtual long Run()
1464	{
1465		for (GLuint i = 0; i < 16; ++i)
1466		{
1467			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
1468		}
1469		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1470		glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 2, NULL, GL_STATIC_DRAW);
1471		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);
1472		glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);
1473		glBindBuffer(GL_ARRAY_BUFFER, 0);
1474
1475		glBindVertexArray(m_vao);
1476
1477		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1478		glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 12, 0);
1479		glBindBuffer(GL_ARRAY_BUFFER, 0);
1480
1481		glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
1482		glVertexAttribBinding(0, 1);
1483
1484		glEnableVertexAttribArray(0);
1485		glEnableVertexAttribArray(1);
1486
1487		expected_data[0]	  = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
1488		expected_data[1]	  = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
1489		expected_data[0 + 16] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
1490		expected_data[1 + 16] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
1491		return BasicInputBase::Run();
1492	}
1493};
1494
1495//=============================================================================
1496// BasicInputIBase
1497//-----------------------------------------------------------------------------
1498class BasicInputIBase : public VertexAttribBindingBase
1499{
1500	GLuint m_po, m_xfbo;
1501
1502protected:
1503	IVec4   expected_datai[32];
1504	UVec4   expected_dataui[32];
1505	GLsizei instance_count;
1506	GLuint  base_instance;
1507
1508	virtual long Setup()
1509	{
1510		m_po = 0;
1511		glGenBuffers(1, &m_xfbo);
1512		for (int i = 0; i < 32; ++i)
1513		{
1514			expected_datai[i]  = IVec4(0);
1515			expected_dataui[i] = UVec4(0);
1516		}
1517		instance_count = 1;
1518		base_instance  = 0;
1519		return NO_ERROR;
1520	}
1521
1522	virtual long Cleanup()
1523	{
1524		glDisable(GL_RASTERIZER_DISCARD);
1525		glUseProgram(0);
1526		glDeleteProgram(m_po);
1527		glDeleteBuffers(1, &m_xfbo);
1528		return NO_ERROR;
1529	}
1530
1531	virtual long Run()
1532	{
1533		const char* const glsl_vs =
1534			"#version 430 core" NL "layout(location = 0) in ivec4 vs_in_attribi[8];" NL
1535			"layout(location = 8) in uvec4 vs_in_attribui[8];" NL "out StageData {" NL "  ivec4 attribi[8];" NL
1536			"  uvec4 attribui[8];" NL "} vs_out;" NL "void main() {" NL
1537			"  for (int i = 0; i < vs_in_attribi.length(); ++i) {" NL "    vs_out.attribi[i] = vs_in_attribi[i];" NL
1538			"  }" NL "  for (int i = 0; i < vs_in_attribui.length(); ++i) {" NL
1539			"    vs_out.attribui[i] = vs_in_attribui[i];" NL "  }" NL "}";
1540		m_po = glCreateProgram();
1541		{
1542			const GLuint sh = glCreateShader(GL_VERTEX_SHADER);
1543			glShaderSource(sh, 1, &glsl_vs, NULL);
1544			glCompileShader(sh);
1545			glAttachShader(m_po, sh);
1546			glDeleteShader(sh);
1547		}
1548		{
1549			const GLchar* const v[16] = { "StageData.attribi[0]",  "StageData.attribi[1]",  "StageData.attribi[2]",
1550										  "StageData.attribi[3]",  "StageData.attribi[4]",  "StageData.attribi[5]",
1551										  "StageData.attribi[6]",  "StageData.attribi[7]",  "StageData.attribui[0]",
1552										  "StageData.attribui[1]", "StageData.attribui[2]", "StageData.attribui[3]",
1553										  "StageData.attribui[4]", "StageData.attribui[5]", "StageData.attribui[6]",
1554										  "StageData.attribui[7]" };
1555			glTransformFeedbackVaryings(m_po, 16, v, GL_INTERLEAVED_ATTRIBS);
1556		}
1557		glLinkProgram(m_po);
1558		if (!CheckProgram(m_po))
1559			return ERROR;
1560
1561		{
1562			std::vector<GLubyte> zero(64 * 16);
1563			glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_xfbo);
1564			glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, (GLsizeiptr)zero.size(), &zero[0], GL_DYNAMIC_COPY);
1565		}
1566
1567		glEnable(GL_RASTERIZER_DISCARD);
1568		glUseProgram(m_po);
1569		glBeginTransformFeedback(GL_POINTS);
1570		glDrawArraysInstancedBaseInstance(GL_POINTS, 0, 2, instance_count, base_instance);
1571		glEndTransformFeedback();
1572
1573		IVec4 datai[32];
1574		glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0 * 16 * 8, 16 * 8, &datai[0]);
1575		glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 2 * 16 * 8, 16 * 8, &datai[8]);
1576		glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 4 * 16 * 8, 16 * 8, &datai[16]);
1577		glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 6 * 16 * 8, 16 * 8, &datai[24]);
1578		UVec4 dataui[32];
1579		glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 1 * 16 * 8, 16 * 8, &dataui[0]);
1580		glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 3 * 16 * 8, 16 * 8, &dataui[8]);
1581		glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 5 * 16 * 8, 16 * 8, &dataui[16]);
1582		glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 7 * 16 * 8, 16 * 8, &dataui[24]);
1583
1584		for (int i = 0; i < 32; ++i)
1585		{
1586			if (!IsEqual(expected_datai[i], datai[i]))
1587			{
1588				m_context.getTestContext().getLog()
1589					<< tcu::TestLog::Message << "Datai is: " << datai[i][0] << " " << datai[i][1] << " " << datai[i][2]
1590					<< " " << datai[i][3] << ", datai should be: " << expected_datai[i][0] << " "
1591					<< expected_datai[i][1] << " " << expected_datai[i][2] << " " << expected_datai[i][3]
1592					<< ", index is: " << i << tcu::TestLog::EndMessage;
1593				return ERROR;
1594			}
1595			if (!IsEqual(expected_dataui[i], dataui[i]))
1596			{
1597				m_context.getTestContext().getLog()
1598					<< tcu::TestLog::Message << "Dataui is: " << dataui[i][0] << " " << dataui[i][1] << " "
1599					<< dataui[i][2] << " " << dataui[i][3] << ", dataui should be: " << expected_dataui[i][0] << " "
1600					<< expected_dataui[i][1] << " " << expected_dataui[i][2] << " " << expected_dataui[i][3]
1601					<< ", index is: " << i << tcu::TestLog::EndMessage;
1602				return ERROR;
1603			}
1604		}
1605		return NO_ERROR;
1606	}
1607};
1608
1609//=============================================================================
1610// 1.3.1 BasicInputICase1
1611//-----------------------------------------------------------------------------
1612class BasicInputICase1 : public BasicInputIBase
1613{
1614	GLuint m_vao, m_vbo;
1615
1616	virtual long Setup()
1617	{
1618		BasicInputIBase::Setup();
1619		glGenVertexArrays(1, &m_vao);
1620		glGenBuffers(1, &m_vbo);
1621		return NO_ERROR;
1622	}
1623
1624	virtual long Cleanup()
1625	{
1626		BasicInputIBase::Cleanup();
1627		glDeleteVertexArrays(1, &m_vao);
1628		glDeleteBuffers(1, &m_vbo);
1629		return NO_ERROR;
1630	}
1631
1632	virtual long Run()
1633	{
1634		for (GLuint i = 0; i < 8; ++i)
1635		{
1636			glVertexAttribI4i(i, 0, 0, 0, 0);
1637			glVertexAttribI4ui(i + 8, 0, 0, 0, 0);
1638		}
1639		const int kStride = 88;
1640		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1641		glBufferData(GL_ARRAY_BUFFER, kStride * 2, NULL, GL_STATIC_DRAW);
1642		{
1643			GLbyte d[] = { 1, -2, 3, -4 };
1644			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
1645		}
1646		{
1647			GLshort d[] = { 5, -6, 7, -8 };
1648			glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);
1649		}
1650		{
1651			GLint d[] = { 9, -10, 11, -12 };
1652			glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);
1653		}
1654		{
1655			GLubyte d[] = { 13, 14, 15, 16 };
1656			glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(d), d);
1657		}
1658		{
1659			GLushort d[] = { 17, 18, 19, 20 };
1660			glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);
1661		}
1662		{
1663			GLuint d[] = { 21, 22, 23, 24 };
1664			glBufferSubData(GL_ARRAY_BUFFER, 40, sizeof(d), d);
1665		}
1666		{
1667			GLint d[] = { 90, -91, 92, -93 };
1668			glBufferSubData(GL_ARRAY_BUFFER, 56, sizeof(d), d);
1669		}
1670		{
1671			GLuint d[] = { 94, 95, 96, 97 };
1672			glBufferSubData(GL_ARRAY_BUFFER, 72, sizeof(d), d);
1673		}
1674
1675		{
1676			GLbyte d[] = { 25, -26, 27, -28 };
1677			glBufferSubData(GL_ARRAY_BUFFER, 0 + kStride, sizeof(d), d);
1678		}
1679		{
1680			GLshort d[] = { 29, -30, 31, -32 };
1681			glBufferSubData(GL_ARRAY_BUFFER, 4 + kStride, sizeof(d), d);
1682		}
1683		{
1684			GLint d[] = { 33, -34, 35, -36 };
1685			glBufferSubData(GL_ARRAY_BUFFER, 12 + kStride, sizeof(d), d);
1686		}
1687		{
1688			GLubyte d[] = { 37, 38, 39, 40 };
1689			glBufferSubData(GL_ARRAY_BUFFER, 28 + kStride, sizeof(d), d);
1690		}
1691		{
1692			GLushort d[] = { 41, 42, 43, 44 };
1693			glBufferSubData(GL_ARRAY_BUFFER, 32 + kStride, sizeof(d), d);
1694		}
1695		{
1696			GLuint d[] = { 45, 46, 47, 48 };
1697			glBufferSubData(GL_ARRAY_BUFFER, 40 + kStride, sizeof(d), d);
1698		}
1699		{
1700			GLint d[] = { 98, -99, 100, -101 };
1701			glBufferSubData(GL_ARRAY_BUFFER, 56 + kStride, sizeof(d), d);
1702		}
1703		{
1704			GLuint d[] = { 102, 103, 104, 105 };
1705			glBufferSubData(GL_ARRAY_BUFFER, 72 + kStride, sizeof(d), d);
1706		}
1707		glBindBuffer(GL_ARRAY_BUFFER, 0);
1708
1709		glBindVertexArray(m_vao);
1710		glVertexAttribIFormat(0, 1, GL_BYTE, 0);
1711		glVertexAttribIFormat(1, 2, GL_SHORT, 4);
1712		glVertexAttribIFormat(2, 3, GL_INT, 12);
1713		glVertexAttribIFormat(3, 4, GL_INT, 56);
1714		glVertexAttribIFormat(8, 3, GL_UNSIGNED_BYTE, 28);
1715		glVertexAttribIFormat(9, 2, GL_UNSIGNED_SHORT, 32);
1716		glVertexAttribIFormat(10, 1, GL_UNSIGNED_INT, 40);
1717		glVertexAttribIFormat(11, 4, GL_UNSIGNED_INT, 72);
1718		glVertexAttribBinding(0, 0);
1719		glVertexAttribBinding(1, 0);
1720		glVertexAttribBinding(2, 0);
1721		glVertexAttribBinding(3, 0);
1722		glVertexAttribBinding(8, 0);
1723		glVertexAttribBinding(9, 0);
1724		glVertexAttribBinding(10, 0);
1725		glVertexAttribBinding(11, 0);
1726		glBindVertexBuffer(0, m_vbo, 0, kStride);
1727		glEnableVertexAttribArray(0);
1728		glEnableVertexAttribArray(1);
1729		glEnableVertexAttribArray(2);
1730		glEnableVertexAttribArray(3);
1731		glEnableVertexAttribArray(8);
1732		glEnableVertexAttribArray(9);
1733		glEnableVertexAttribArray(10);
1734		glEnableVertexAttribArray(11);
1735
1736		expected_datai[0]   = IVec4(1, 0, 0, 1);
1737		expected_datai[1]   = IVec4(5, -6, 0, 1);
1738		expected_datai[2]   = IVec4(9, -10, 11, 1);
1739		expected_datai[3]   = IVec4(90, -91, 92, -93);
1740		expected_dataui[0]  = UVec4(13, 14, 15, 1);
1741		expected_dataui[1]  = UVec4(17, 18, 0, 1);
1742		expected_dataui[2]  = UVec4(21, 0, 0, 1);
1743		expected_dataui[3]  = UVec4(94, 95, 96, 97);
1744		expected_datai[8]   = IVec4(25, 0, 0, 1);
1745		expected_datai[9]   = IVec4(29, -30, 0, 1);
1746		expected_datai[10]  = IVec4(33, -34, 35, 1);
1747		expected_datai[11]  = IVec4(98, -99, 100, -101);
1748		expected_dataui[8]  = UVec4(37, 38, 39, 1);
1749		expected_dataui[9]  = UVec4(41, 42, 0, 1);
1750		expected_dataui[10] = UVec4(45, 0, 0, 1);
1751		expected_dataui[11] = UVec4(102, 103, 104, 105);
1752		return BasicInputIBase::Run();
1753	}
1754};
1755
1756//=============================================================================
1757// 1.3.2 BasicInputICase2
1758//-----------------------------------------------------------------------------
1759class BasicInputICase2 : public BasicInputIBase
1760{
1761	GLuint m_vao, m_vbo[2];
1762
1763	virtual long Setup()
1764	{
1765		BasicInputIBase::Setup();
1766		glGenVertexArrays(1, &m_vao);
1767		glGenBuffers(2, m_vbo);
1768		return NO_ERROR;
1769	}
1770
1771	virtual long Cleanup()
1772	{
1773		BasicInputIBase::Cleanup();
1774		glDeleteVertexArrays(1, &m_vao);
1775		glDeleteBuffers(2, m_vbo);
1776		return NO_ERROR;
1777	}
1778
1779	virtual long Run()
1780	{
1781		for (GLuint i = 0; i < 8; ++i)
1782		{
1783			glVertexAttribI4i(i, 0, 0, 0, 0);
1784			glVertexAttribI4ui(i + 8, 0, 0, 0, 0);
1785		}
1786		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
1787		glBufferData(GL_ARRAY_BUFFER, sizeof(IVec3) * 2, NULL, GL_STATIC_DRAW);
1788		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(IVec3), &IVec3(1, 2, 3)[0]);
1789		glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(IVec3), &IVec3(4, 5, 6)[0]);
1790
1791		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
1792		glBufferData(GL_ARRAY_BUFFER, sizeof(UVec4), NULL, GL_STATIC_DRAW);
1793		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(UVec4), &UVec4(10, 20, 30, 40)[0]);
1794		glBindBuffer(GL_ARRAY_BUFFER, 0);
1795
1796		glBindVertexArray(m_vao);
1797		glVertexAttribIFormat(0, 3, GL_INT, 0);
1798		glVertexAttribIFormat(2, 2, GL_INT, 4);
1799		glVertexAttribIFormat(15, 1, GL_UNSIGNED_INT, 0);
1800		glVertexAttribBinding(0, 2);
1801		glVertexAttribBinding(2, 0);
1802		glVertexAttribBinding(15, 7);
1803		glEnableVertexAttribArray(0);
1804		glEnableVertexAttribArray(2);
1805		glEnableVertexAttribArray(15);
1806		glBindVertexBuffer(0, m_vbo[0], 0, 8);
1807		glBindVertexBuffer(2, m_vbo[0], 0, 12);
1808		glBindVertexBuffer(7, m_vbo[1], 4, 16);
1809		glVertexBindingDivisor(0, 1);
1810		glVertexBindingDivisor(2, 0);
1811		glVertexBindingDivisor(7, 2);
1812
1813		instance_count		= 2;
1814		expected_datai[0]   = IVec4(1, 2, 3, 1);
1815		expected_datai[2]   = IVec4(2, 3, 0, 1);
1816		expected_dataui[7]  = UVec4(20, 0, 0, 1);
1817		expected_datai[8]   = IVec4(4, 5, 6, 1);
1818		expected_datai[10]  = IVec4(2, 3, 0, 1);
1819		expected_dataui[15] = UVec4(20, 0, 0, 1);
1820
1821		expected_datai[16]  = IVec4(1, 2, 3, 1);
1822		expected_datai[18]  = IVec4(4, 5, 0, 1);
1823		expected_dataui[23] = UVec4(20, 0, 0, 1);
1824		expected_datai[24]  = IVec4(4, 5, 6, 1);
1825		expected_datai[26]  = IVec4(4, 5, 0, 1);
1826		expected_dataui[31] = UVec4(20, 0, 0, 1);
1827		return BasicInputIBase::Run();
1828	}
1829};
1830
1831//=============================================================================
1832// 1.3.3 BasicInputICase3
1833//-----------------------------------------------------------------------------
1834class BasicInputICase3 : public BasicInputIBase
1835{
1836	GLuint m_vao, m_vbo;
1837
1838	virtual long Setup()
1839	{
1840		BasicInputIBase::Setup();
1841		glGenVertexArrays(1, &m_vao);
1842		glGenBuffers(1, &m_vbo);
1843		return NO_ERROR;
1844	}
1845
1846	virtual long Cleanup()
1847	{
1848		BasicInputIBase::Cleanup();
1849		glDeleteVertexArrays(1, &m_vao);
1850		glDeleteBuffers(1, &m_vbo);
1851		return NO_ERROR;
1852	}
1853
1854	virtual long Run()
1855	{
1856		for (GLuint i = 0; i < 8; ++i)
1857		{
1858			glVertexAttribI4i(i, 0, 0, 0, 0);
1859			glVertexAttribI4ui(i + 8, 0, 0, 0, 0);
1860		}
1861		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1862		glBufferData(GL_ARRAY_BUFFER, sizeof(IVec3) * 2, NULL, GL_STATIC_DRAW);
1863		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(IVec3), &IVec3(1, 2, 3)[0]);
1864		glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(IVec3), &IVec3(4, 5, 6)[0]);
1865		glBindBuffer(GL_ARRAY_BUFFER, 0);
1866
1867		glBindVertexArray(m_vao);
1868
1869		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1870		glVertexAttribIPointer(7, 3, GL_INT, 12, 0);
1871		glBindBuffer(GL_ARRAY_BUFFER, 0);
1872
1873		glVertexAttribIFormat(0, 2, GL_INT, 4);
1874		glVertexAttribBinding(0, 7);
1875
1876		glEnableVertexAttribArray(0);
1877		glEnableVertexAttribArray(7);
1878
1879		expected_datai[0]	 = IVec4(2, 3, 0, 1);
1880		expected_datai[7]	 = IVec4(1, 2, 3, 1);
1881		expected_datai[0 + 8] = IVec4(5, 6, 0, 1);
1882		expected_datai[7 + 8] = IVec4(4, 5, 6, 1);
1883		return BasicInputIBase::Run();
1884	}
1885};
1886
1887//=============================================================================
1888// BasicInputLBase
1889//-----------------------------------------------------------------------------
1890class BasicInputLBase : public VertexAttribBindingBase
1891{
1892	GLuint m_po, m_xfbo;
1893
1894protected:
1895	DVec4   expected_data[32];
1896	GLsizei instance_count;
1897	GLuint  base_instance;
1898
1899	virtual long Setup()
1900	{
1901		m_po = 0;
1902		glGenBuffers(1, &m_xfbo);
1903		for (int i = 0; i < 32; ++i)
1904		{
1905			expected_data[i] = DVec4(0.0);
1906		}
1907		instance_count = 1;
1908		base_instance  = 0;
1909		return NO_ERROR;
1910	}
1911
1912	virtual long Cleanup()
1913	{
1914		glDisable(GL_RASTERIZER_DISCARD);
1915		glUseProgram(0);
1916		glDeleteProgram(m_po);
1917		glDeleteBuffers(1, &m_xfbo);
1918		return NO_ERROR;
1919	}
1920
1921	virtual long Run()
1922	{
1923		const char* const glsl_vs =
1924			"#version 430 core" NL "layout(location = 0) in dvec4 vs_in_attrib[8];" NL "out StageData {" NL
1925			"  dvec4 attrib[8];" NL "} vs_out;" NL "void main() {" NL "  vs_out.attrib[0] = vs_in_attrib[0];" NL
1926			"  vs_out.attrib[1] = vs_in_attrib[1];" NL "  vs_out.attrib[2] = vs_in_attrib[2];" NL
1927			"  vs_out.attrib[3] = vs_in_attrib[3];" NL "  vs_out.attrib[4] = vs_in_attrib[4];" NL
1928			"  vs_out.attrib[5] = vs_in_attrib[5];" NL "  vs_out.attrib[6] = vs_in_attrib[6];" NL
1929			"  vs_out.attrib[7] = vs_in_attrib[7];" NL "}";
1930		m_po = glCreateProgram();
1931		{
1932			const GLuint sh = glCreateShader(GL_VERTEX_SHADER);
1933			glShaderSource(sh, 1, &glsl_vs, NULL);
1934			glCompileShader(sh);
1935			glAttachShader(m_po, sh);
1936			glDeleteShader(sh);
1937		}
1938		{
1939			const GLchar* const v[8] = {
1940				"StageData.attrib[0]", "StageData.attrib[1]", "StageData.attrib[2]", "StageData.attrib[3]",
1941				"StageData.attrib[4]", "StageData.attrib[5]", "StageData.attrib[6]", "StageData.attrib[7]",
1942			};
1943			glTransformFeedbackVaryings(m_po, 8, v, GL_INTERLEAVED_ATTRIBS);
1944		}
1945		glLinkProgram(m_po);
1946		if (!CheckProgram(m_po))
1947			return ERROR;
1948
1949		{
1950			std::vector<GLubyte> zero(sizeof(expected_data));
1951			glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_xfbo);
1952			glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, (GLsizeiptr)zero.size(), &zero[0], GL_DYNAMIC_COPY);
1953		}
1954
1955		glEnable(GL_RASTERIZER_DISCARD);
1956		glUseProgram(m_po);
1957		glBeginTransformFeedback(GL_POINTS);
1958		glDrawArraysInstancedBaseInstance(GL_POINTS, 0, 2, instance_count, base_instance);
1959		glEndTransformFeedback();
1960
1961		DVec4 data[32];
1962		glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(DVec4) * 32, &data[0]);
1963
1964		for (int i = 0; i < 32; ++i)
1965		{
1966			for (int j = 0; j < 4; ++j)
1967			{
1968				if (expected_data[i][j] != 12345.0 && expected_data[i][j] != data[i][j])
1969				{
1970					m_context.getTestContext().getLog()
1971						<< tcu::TestLog::Message << "Data is: " << data[i][0] << " " << data[i][1] << " " << data[i][2]
1972						<< " " << data[i][3] << ", data should be: " << expected_data[i][0] << " "
1973						<< expected_data[i][1] << " " << expected_data[i][2] << " " << expected_data[i][3]
1974						<< ", index is: " << i << tcu::TestLog::EndMessage;
1975					return ERROR;
1976				}
1977			}
1978		}
1979		return NO_ERROR;
1980	}
1981};
1982
1983//=============================================================================
1984// 1.4.1 BasicInputLCase1
1985//-----------------------------------------------------------------------------
1986class BasicInputLCase1 : public BasicInputLBase
1987{
1988	GLuint m_vao, m_vbo;
1989
1990	virtual long Setup()
1991	{
1992		BasicInputLBase::Setup();
1993		glGenVertexArrays(1, &m_vao);
1994		glGenBuffers(1, &m_vbo);
1995		return NO_ERROR;
1996	}
1997
1998	virtual long Cleanup()
1999	{
2000		BasicInputLBase::Cleanup();
2001		glDeleteVertexArrays(1, &m_vao);
2002		glDeleteBuffers(1, &m_vbo);
2003		return NO_ERROR;
2004	}
2005
2006	virtual long Run()
2007	{
2008		for (GLuint i = 0; i < 8; ++i)
2009		{
2010			glVertexAttribL4d(i, 0.0, 0.0, 0.0, 0.0);
2011		}
2012		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
2013		glBufferData(GL_ARRAY_BUFFER, sizeof(DVec4) * 3, NULL, GL_STATIC_DRAW);
2014		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(DVec4), &DVec4(1.0, 2.0, 3.0, 4.0)[0]);
2015		glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(DVec4), &DVec4(5.0, 6.0, 7.0, 8.0)[0]);
2016		glBufferSubData(GL_ARRAY_BUFFER, 64, sizeof(DVec4), &DVec4(9.0, 10.0, 11.0, 12.0)[0]);
2017		glBindBuffer(GL_ARRAY_BUFFER, 0);
2018
2019		glBindVertexArray(m_vao);
2020		glVertexAttribLFormat(0, 4, GL_DOUBLE, 0);
2021		glVertexAttribLFormat(3, 3, GL_DOUBLE, 8);
2022		glVertexAttribLFormat(5, 2, GL_DOUBLE, 0);
2023		glVertexAttribLFormat(7, 1, GL_DOUBLE, 24);
2024		glVertexAttribBinding(0, 0);
2025		glVertexAttribBinding(3, 2);
2026		glVertexAttribBinding(5, 0);
2027		glVertexAttribBinding(7, 6);
2028		glEnableVertexAttribArray(0);
2029		glEnableVertexAttribArray(3);
2030		glEnableVertexAttribArray(5);
2031		glEnableVertexAttribArray(7);
2032		glBindVertexBuffer(0, m_vbo, 0, 32);
2033		glBindVertexBuffer(2, m_vbo, 0, 16);
2034		glBindVertexBuffer(6, m_vbo, 16, 0);
2035
2036		expected_data[0]	 = DVec4(1.0, 2.0, 3.0, 4.0);
2037		expected_data[3]	 = DVec4(2.0, 3.0, 4.0, 12345.0);
2038		expected_data[5]	 = DVec4(1.0, 2.0, 12345.0, 12345.0);
2039		expected_data[7]	 = DVec4(6.0, 12345.0, 12345.0, 12345.0);
2040		expected_data[0 + 8] = DVec4(5.0, 6.0, 7.0, 8.0);
2041		expected_data[3 + 8] = DVec4(4.0, 5.0, 6.0, 12345.0);
2042		expected_data[5 + 8] = DVec4(5.0, 6.0, 12345.0, 12345.0);
2043		expected_data[7 + 8] = DVec4(6.0, 12345.0, 12345.0, 12345.0);
2044		return BasicInputLBase::Run();
2045	}
2046};
2047
2048//=============================================================================
2049// 1.4.2 BasicInputLCase2
2050//-----------------------------------------------------------------------------
2051class BasicInputLCase2 : public BasicInputLBase
2052{
2053	GLuint m_vao, m_vbo[2];
2054
2055	virtual long Setup()
2056	{
2057		BasicInputLBase::Setup();
2058		glGenVertexArrays(1, &m_vao);
2059		glGenBuffers(2, m_vbo);
2060		return NO_ERROR;
2061	}
2062
2063	virtual long Cleanup()
2064	{
2065		BasicInputLBase::Cleanup();
2066		glDeleteVertexArrays(1, &m_vao);
2067		glDeleteBuffers(2, m_vbo);
2068		return NO_ERROR;
2069	}
2070
2071	virtual long Run()
2072	{
2073		for (GLuint i = 0; i < 8; ++i)
2074		{
2075			glVertexAttribL4d(i, 0.0, 0.0, 0.0, 0.0);
2076		}
2077		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
2078		glBufferData(GL_ARRAY_BUFFER, sizeof(DVec4) * 3, NULL, GL_STATIC_DRAW);
2079		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(DVec4), &DVec4(1.0, 2.0, 3.0, 4.0)[0]);
2080		glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(DVec4), &DVec4(5.0, 6.0, 7.0, 8.0)[0]);
2081		glBufferSubData(GL_ARRAY_BUFFER, 64, sizeof(DVec4), &DVec4(9.0, 10.0, 11.0, 12.0)[0]);
2082		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
2083		glBufferData(GL_ARRAY_BUFFER, sizeof(DVec4) * 3, NULL, GL_STATIC_DRAW);
2084		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(DVec4), &DVec4(10.0, 20.0, 30.0, 40.0)[0]);
2085		glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(DVec4), &DVec4(50.0, 60.0, 70.0, 80.0)[0]);
2086		glBindBuffer(GL_ARRAY_BUFFER, 0);
2087
2088		glBindVertexArray(m_vao);
2089		glVertexAttribLFormat(0, 4, GL_DOUBLE, 0);
2090		glVertexAttribLFormat(2, 4, GL_DOUBLE, 0);
2091		glVertexAttribLFormat(4, 2, GL_DOUBLE, 8);
2092		glVertexAttribBinding(0, 0);
2093		glVertexAttribBinding(2, 1);
2094		glVertexAttribBinding(4, 2);
2095		glEnableVertexAttribArray(0);
2096		glEnableVertexAttribArray(2);
2097		glEnableVertexAttribArray(4);
2098		glBindVertexBuffer(0, m_vbo[0], 0, 32);
2099		glBindVertexBuffer(1, m_vbo[0], 0, 32);
2100		glBindVertexBuffer(2, m_vbo[1], 8, 16);
2101		glVertexBindingDivisor(1, 1);
2102
2103		instance_count		 = 2;
2104		expected_data[0]	 = DVec4(1.0, 2.0, 3.0, 4.0);
2105		expected_data[2]	 = DVec4(1.0, 2.0, 3.0, 4.0);
2106		expected_data[4]	 = DVec4(30.0, 40.0, 12345.0, 12345.0);
2107		expected_data[0 + 8] = DVec4(5.0, 6.0, 7.0, 8.0);
2108		expected_data[2 + 8] = DVec4(1.0, 2.0, 3.0, 4.0);
2109		expected_data[4 + 8] = DVec4(50.0, 60.0, 12345.0, 12345.0);
2110
2111		expected_data[0 + 16]	 = DVec4(1.0, 2.0, 3.0, 4.0);
2112		expected_data[2 + 16]	 = DVec4(5.0, 6.0, 7.0, 8.0);
2113		expected_data[4 + 16]	 = DVec4(30.0, 40.0, 12345.0, 12345.0);
2114		expected_data[0 + 8 + 16] = DVec4(5.0, 6.0, 7.0, 8.0);
2115		expected_data[2 + 8 + 16] = DVec4(5.0, 6.0, 7.0, 8.0);
2116		expected_data[4 + 8 + 16] = DVec4(50.0, 60.0, 12345.0, 12345.0);
2117		return BasicInputLBase::Run();
2118	}
2119};
2120
2121//=============================================================================
2122// 1.5 BasicState1
2123//-----------------------------------------------------------------------------
2124class BasicState1 : public VertexAttribBindingBase
2125{
2126	GLuint m_vao, m_vbo[2];
2127
2128	virtual long Setup()
2129	{
2130		glGenVertexArrays(1, &m_vao);
2131		glGenBuffers(2, m_vbo);
2132		return NO_ERROR;
2133	}
2134
2135	virtual long Cleanup()
2136	{
2137		glDeleteVertexArrays(1, &m_vao);
2138		glDeleteBuffers(2, m_vbo);
2139		return NO_ERROR;
2140	}
2141
2142	virtual long Run()
2143	{
2144		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
2145		glBufferData(GL_ARRAY_BUFFER, 1000, NULL, GL_DYNAMIC_COPY);
2146		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
2147		glBufferData(GL_ARRAY_BUFFER, 1000, NULL, GL_DYNAMIC_COPY);
2148		glBindBuffer(GL_ARRAY_BUFFER, 0);
2149
2150		GLint p;
2151		glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &p);
2152		if (p < 16)
2153		{
2154			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_BINDINGS is " << p
2155												<< " but must be at least 16." << tcu::TestLog::EndMessage;
2156			return ERROR;
2157		}
2158		glGetIntegerv(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
2159		if (p < 2047)
2160		{
2161			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET is "
2162												<< p << " but must be at least 2047." << tcu::TestLog::EndMessage;
2163			return ERROR;
2164		}
2165
2166		glBindVertexArray(m_vao);
2167		// check default state
2168		for (GLuint i = 0; i < 16; ++i)
2169		{
2170			glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_BINDING, &p);
2171			if (static_cast<GLint>(i) != p)
2172			{
2173				m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_BINDING(" << i
2174													<< ") is " << p << " should be " << i << tcu::TestLog::EndMessage;
2175				return ERROR;
2176			}
2177			glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
2178			if (p != 0)
2179			{
2180				m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_RELATIVE_OFFSET(" << i
2181													<< ") is " << p << " should be 0." << tcu::TestLog::EndMessage;
2182				return ERROR;
2183			}
2184			GLint64 p64;
2185			glGetInteger64i_v(GL_VERTEX_BINDING_OFFSET, i, &p64);
2186			if (p64 != 0)
2187			{
2188				m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_OFFSET(" << i
2189													<< ") should be 0." << tcu::TestLog::EndMessage;
2190				return ERROR;
2191			}
2192			glGetIntegeri_v(GL_VERTEX_BINDING_STRIDE, i, &p);
2193			if (p != 16)
2194			{
2195				m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_STRIDE(" << i
2196													<< ") is " << p << " should be 16." << tcu::TestLog::EndMessage;
2197				return ERROR;
2198			}
2199		}
2200		glVertexAttribFormat(0, 2, GL_BYTE, GL_TRUE, 16);
2201		glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_SIZE, &p);
2202		if (p != 2)
2203		{
2204			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_SIZE(0) is " << p
2205												<< " should be 2." << tcu::TestLog::EndMessage;
2206			return ERROR;
2207		}
2208		glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_TYPE, &p);
2209		if (p != GL_BYTE)
2210		{
2211			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_TYPE(0) is " << p
2212												<< " should be GL_BYTE." << tcu::TestLog::EndMessage;
2213			return ERROR;
2214		}
2215		glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &p);
2216		if (p != GL_TRUE)
2217		{
2218			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED(0) is "
2219												<< p << " should be GL_TRUE." << tcu::TestLog::EndMessage;
2220			return ERROR;
2221		}
2222		glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
2223		if (p != 16)
2224		{
2225			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_RELATIVE_OFFSET(0) is "
2226												<< p << " should be 16." << tcu::TestLog::EndMessage;
2227			return ERROR;
2228		}
2229
2230		glVertexAttribIFormat(2, 3, GL_INT, 512);
2231		glGetVertexAttribiv(2, GL_VERTEX_ATTRIB_ARRAY_SIZE, &p);
2232		if (p != 3)
2233		{
2234			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_SIZE(2) is " << p
2235												<< " should be 3." << tcu::TestLog::EndMessage;
2236			return ERROR;
2237		}
2238		glGetVertexAttribiv(2, GL_VERTEX_ATTRIB_ARRAY_TYPE, &p);
2239		if (p != GL_INT)
2240		{
2241			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_TYPE(2) is " << p
2242												<< " should be GL_INT." << tcu::TestLog::EndMessage;
2243			return ERROR;
2244		}
2245		glGetVertexAttribiv(2, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
2246		if (p != 512)
2247		{
2248			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_RELATIVE_OFFSET(2) is "
2249												<< p << " should be 512." << tcu::TestLog::EndMessage;
2250			return ERROR;
2251		}
2252		glGetVertexAttribiv(2, GL_VERTEX_ATTRIB_ARRAY_INTEGER, &p);
2253		if (p != GL_TRUE)
2254		{
2255			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_INTEGER(2) is " << p
2256												<< " should be GL_TRUE." << tcu::TestLog::EndMessage;
2257			return ERROR;
2258		}
2259
2260		glVertexAttribLFormat(15, 1, GL_DOUBLE, 1024);
2261		glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_ARRAY_SIZE, &p);
2262		if (p != 1)
2263		{
2264			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_SIZE(15) is " << p
2265												<< " should be 1." << tcu::TestLog::EndMessage;
2266			return ERROR;
2267		}
2268		glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_ARRAY_TYPE, &p);
2269		if (p != GL_DOUBLE)
2270		{
2271			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_TYPE(15) is " << p
2272												<< " should be GL_DOUBLE." << tcu::TestLog::EndMessage;
2273			return ERROR;
2274		}
2275		glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
2276		if (p != 1024)
2277		{
2278			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_TYPE(15) is " << p
2279												<< " should be 1024." << tcu::TestLog::EndMessage;
2280			return ERROR;
2281		}
2282		glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_ARRAY_LONG, &p);
2283		if (p != GL_TRUE)
2284		{
2285			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_LONG(15) is " << p
2286												<< " should be GL_TRUE." << tcu::TestLog::EndMessage;
2287			return ERROR;
2288		}
2289
2290		glVertexAttribBinding(0, 7);
2291		glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_BINDING, &p);
2292		if (p != 7)
2293			return ERROR;
2294		glVertexAttribBinding(3, 7);
2295		glGetVertexAttribiv(3, GL_VERTEX_ATTRIB_BINDING, &p);
2296		if (p != 7)
2297			return ERROR;
2298		glVertexAttribBinding(9, 0);
2299		glGetVertexAttribiv(9, GL_VERTEX_ATTRIB_BINDING, &p);
2300		if (p != 0)
2301			return ERROR;
2302		glVertexAttribBinding(15, 1);
2303		glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_BINDING, &p);
2304		if (p != 1)
2305			return ERROR;
2306		glVertexAttribBinding(15, 15);
2307		glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_BINDING, &p);
2308		if (p != 15)
2309			return ERROR;
2310
2311		glBindVertexBuffer(0, m_vbo[0], 1024, 128);
2312		GLint64 p64;
2313		glGetInteger64i_v(GL_VERTEX_BINDING_OFFSET, 0, &p64);
2314		if (p64 != 1024)
2315		{
2316			m_context.getTestContext().getLog()
2317				<< tcu::TestLog::Message << "GL_VERTEX_BINDING_OFFSET(0) should be 1024." << tcu::TestLog::EndMessage;
2318			return ERROR;
2319		}
2320		glGetIntegeri_v(GL_VERTEX_BINDING_STRIDE, 0, &p);
2321		if (p != 128)
2322		{
2323			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_STRIDE(0) is " << p
2324												<< "should be 128." << tcu::TestLog::EndMessage;
2325			return ERROR;
2326		}
2327		glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &p);
2328		if (p != 0)
2329		{
2330			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_STRIDE(0) is " << p
2331												<< "should be 0." << tcu::TestLog::EndMessage;
2332			return ERROR;
2333		}
2334		glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &p);
2335		if (p != 0)
2336		{
2337			m_context.getTestContext().getLog()
2338				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING(0) is " << p << "should be 0."
2339				<< tcu::TestLog::EndMessage;
2340			return ERROR;
2341		}
2342
2343		glBindVertexBuffer(15, m_vbo[1], 16, 32);
2344		glGetInteger64i_v(GL_VERTEX_BINDING_OFFSET, 15, &p64);
2345		if (p64 != 16)
2346		{
2347			m_context.getTestContext().getLog()
2348				<< tcu::TestLog::Message << "GL_VERTEX_BINDING_OFFSET(15) should be 16." << tcu::TestLog::EndMessage;
2349			return ERROR;
2350		}
2351		glGetIntegeri_v(GL_VERTEX_BINDING_STRIDE, 15, &p);
2352		if (p != 32)
2353		{
2354			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_STRIDE(15) is " << p
2355												<< " should be 32." << tcu::TestLog::EndMessage;
2356			return ERROR;
2357		}
2358		glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &p);
2359		if (p != 0)
2360		{
2361			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_STRIDE(15) is " << p
2362												<< " should be 0." << tcu::TestLog::EndMessage;
2363			return ERROR;
2364		}
2365		glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &p);
2366		if (p != static_cast<GLint>(m_vbo[1]))
2367		{
2368			m_context.getTestContext().getLog()
2369				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING(15) is " << p << " should be "
2370				<< m_vbo[1] << tcu::TestLog::EndMessage;
2371			return ERROR;
2372		}
2373
2374		return NO_ERROR;
2375	}
2376};
2377
2378//=============================================================================
2379// 1.6 BasicState2
2380//-----------------------------------------------------------------------------
2381class BasicState2 : public VertexAttribBindingBase
2382{
2383	GLuint m_vao, m_vbo;
2384
2385	virtual long Setup()
2386	{
2387		glGenVertexArrays(1, &m_vao);
2388		glGenBuffers(1, &m_vbo);
2389		return NO_ERROR;
2390	}
2391
2392	virtual long Cleanup()
2393	{
2394		glDeleteVertexArrays(1, &m_vao);
2395		glDeleteBuffers(1, &m_vbo);
2396		return NO_ERROR;
2397	}
2398
2399	virtual long Run()
2400	{
2401		GLint p;
2402		glBindVertexArray(m_vao);
2403		for (GLuint i = 0; i < 16; ++i)
2404		{
2405			glGetIntegeri_v(GL_VERTEX_BINDING_DIVISOR, i, &p);
2406			if (glGetError() != GL_NO_ERROR)
2407			{
2408				m_context.getTestContext().getLog()
2409					<< tcu::TestLog::Message
2410					<< "glGetIntegeri_v(GL_VERTEX_BINDING_DIVISOR, ...) command generates error."
2411					<< tcu::TestLog::EndMessage;
2412				return ERROR;
2413			}
2414			if (p != 0)
2415			{
2416				m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_DIVISOR(" << i
2417													<< ") is " << p << " should be 0." << tcu::TestLog::EndMessage;
2418				return ERROR;
2419			}
2420		}
2421		glVertexBindingDivisor(1, 2);
2422		glGetIntegeri_v(GL_VERTEX_BINDING_DIVISOR, 1, &p);
2423		if (p != 2)
2424		{
2425			m_context.getTestContext().getLog()
2426				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_DIVISOR(1) is %d should be 2."
2427				<< tcu::TestLog::EndMessage;
2428			return ERROR;
2429		}
2430		return NO_ERROR;
2431	}
2432};
2433
2434class VertexAttribState : public deqp::GLWrapper
2435{
2436public:
2437	int		  array_enabled;
2438	int		  array_size;
2439	int		  array_stride;
2440	int		  array_type;
2441	int		  array_normalized;
2442	int		  array_integer;
2443	int		  array_long;
2444	int		  array_divisor;
2445	deUintptr array_pointer;
2446	int		  array_buffer_binding;
2447	int		  binding;
2448	int		  relative_offset;
2449	int		  index;
2450
2451	VertexAttribState(int attribindex)
2452		: array_enabled(0)
2453		, array_size(4)
2454		, array_stride(0)
2455		, array_type(GL_FLOAT)
2456		, array_normalized(0)
2457		, array_integer(0)
2458		, array_long(0)
2459		, array_divisor(0)
2460		, array_pointer(0)
2461		, array_buffer_binding(0)
2462		, binding(attribindex)
2463		, relative_offset(0)
2464		, index(attribindex)
2465	{
2466	}
2467
2468	bool stateVerify()
2469	{
2470		GLint p;
2471		bool  status = true;
2472		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &p);
2473		if (p != array_enabled)
2474		{
2475			m_context.getTestContext().getLog()
2476				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_ENABLED(" << index << ") is " << p << " should be "
2477				<< array_enabled << tcu::TestLog::EndMessage;
2478			status = false;
2479		}
2480		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_SIZE, &p);
2481		if (p != array_size)
2482		{
2483			m_context.getTestContext().getLog()
2484				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_SIZE(" << index << ") is " << p << " should be "
2485				<< array_size << tcu::TestLog::EndMessage;
2486			status = false;
2487		}
2488		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &p);
2489		if (p != array_stride)
2490		{
2491			m_context.getTestContext().getLog()
2492				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_STRIDE(" << index << ") is " << p << " should be "
2493				<< array_stride << tcu::TestLog::EndMessage;
2494			status = false;
2495		}
2496		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_TYPE, &p);
2497		if (p != array_type)
2498		{
2499			m_context.getTestContext().getLog()
2500				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_TYPE(" << index << ") is " << tcu::toHex(p)
2501				<< " should be " << tcu::toHex(array_type) << tcu::TestLog::EndMessage;
2502			status = false;
2503		}
2504		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &p);
2505		if (p != array_normalized)
2506		{
2507			m_context.getTestContext().getLog()
2508				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED(" << index << ") is " << p
2509				<< " should be " << array_normalized << tcu::TestLog::EndMessage;
2510			status = false;
2511		}
2512		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_INTEGER, &p);
2513		if (p != array_integer)
2514		{
2515			m_context.getTestContext().getLog()
2516				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_INTEGER(" << index << ") is " << p << " should be "
2517				<< array_integer << tcu::TestLog::EndMessage;
2518			status = false;
2519		}
2520		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_LONG, &p);
2521		if (p != array_long)
2522		{
2523			m_context.getTestContext().getLog()
2524				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_LONG(" << index << ") is " << p << " should be "
2525				<< array_long << tcu::TestLog::EndMessage;
2526			status = false;
2527		}
2528		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, &p);
2529		if (p != array_divisor)
2530		{
2531			m_context.getTestContext().getLog()
2532				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_DIVISOR(" << index << ") is " << p << " should be "
2533				<< array_divisor << tcu::TestLog::EndMessage;
2534			status = false;
2535		}
2536		void* pp;
2537		glGetVertexAttribPointerv(index, GL_VERTEX_ATTRIB_ARRAY_POINTER, &pp);
2538		if (reinterpret_cast<deUintptr>(pp) != array_pointer)
2539		{
2540			m_context.getTestContext().getLog()
2541				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_POINTER(" << index << ") is "
2542				<< reinterpret_cast<deUintptr>(pp) << " should be " << array_pointer << tcu::TestLog::EndMessage;
2543			status = false;
2544		}
2545		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &p);
2546		if (p != array_buffer_binding)
2547		{
2548			m_context.getTestContext().getLog()
2549				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING(" << index << ") is " << p
2550				<< " should be " << array_buffer_binding << tcu::TestLog::EndMessage;
2551			status = false;
2552		}
2553		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_BINDING, &p);
2554		if (static_cast<GLint>(binding) != p)
2555		{
2556			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_BINDING(" << index
2557												<< ") is " << p << " should be " << binding << tcu::TestLog::EndMessage;
2558			status = false;
2559		}
2560		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
2561		if (p != relative_offset)
2562		{
2563			m_context.getTestContext().getLog()
2564				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_RELATIVE_OFFSET(" << index << ") is " << p
2565				<< " should be " << relative_offset << tcu::TestLog::EndMessage;
2566			status = false;
2567		}
2568		return status;
2569	}
2570};
2571
2572class VertexBindingState : public deqp::GLWrapper
2573{
2574public:
2575	int		 buffer;
2576	long int offset;
2577	int		 stride;
2578	int		 divisor;
2579	int		 index;
2580
2581	VertexBindingState(int bindingindex) : buffer(0), offset(0), stride(16), divisor(0), index(bindingindex)
2582	{
2583	}
2584
2585	bool stateVerify()
2586	{
2587		bool  status = true;
2588		GLint p;
2589		glGetIntegeri_v(GL_VERTEX_BINDING_BUFFER, index, &p);
2590		if (p != buffer)
2591		{
2592			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_BUFFER(" << index
2593												<< ") is " << p << " should be " << buffer << tcu::TestLog::EndMessage;
2594			status = false;
2595		}
2596		GLint64 p64;
2597		glGetInteger64i_v(GL_VERTEX_BINDING_OFFSET, index, &p64);
2598		if (p64 != offset)
2599		{
2600			m_context.getTestContext().getLog()
2601				<< tcu::TestLog::Message << "GL_VERTEX_BINDING_OFFSET(" << index << ") is " << p64 << " should be "
2602				<< offset << tcu::TestLog::EndMessage;
2603			status = false;
2604		}
2605		glGetIntegeri_v(GL_VERTEX_BINDING_STRIDE, index, &p);
2606		if (p != stride)
2607		{
2608			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_STRIDE(" << index
2609												<< ") is " << p << " should be " << stride << tcu::TestLog::EndMessage;
2610			status = false;
2611		}
2612		glGetIntegeri_v(GL_VERTEX_BINDING_DIVISOR, index, &p);
2613		if (p != divisor)
2614		{
2615			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_DIVISOR(" << index
2616												<< ") is " << p << " should be " << divisor << tcu::TestLog::EndMessage;
2617			status = false;
2618		}
2619		return status;
2620	}
2621};
2622
2623//=============================================================================
2624// 1.6 BasicState3
2625//-----------------------------------------------------------------------------
2626class BasicState3 : public VertexAttribBindingBase
2627{
2628
2629	GLuint m_vao, m_vbo[3];
2630
2631	virtual long Setup()
2632	{
2633		glGenVertexArrays(1, &m_vao);
2634		glGenBuffers(3, m_vbo);
2635		return NO_ERROR;
2636	}
2637
2638	virtual long Cleanup()
2639	{
2640		glDeleteVertexArrays(1, &m_vao);
2641		glDeleteBuffers(3, m_vbo);
2642		return NO_ERROR;
2643	}
2644
2645	virtual long Run()
2646	{
2647		bool status = true;
2648		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
2649		glBufferData(GL_ARRAY_BUFFER, 10000, NULL, GL_DYNAMIC_COPY);
2650		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
2651		glBufferData(GL_ARRAY_BUFFER, 10000, NULL, GL_DYNAMIC_COPY);
2652		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[2]);
2653		glBufferData(GL_ARRAY_BUFFER, 10000, NULL, GL_DYNAMIC_COPY);
2654		glBindBuffer(GL_ARRAY_BUFFER, 0);
2655
2656		GLint p;
2657		glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &p);
2658		if (p < 16)
2659		{
2660			m_context.getTestContext().getLog()
2661				<< tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_BINDINGS is %d but must be at least 16."
2662				<< tcu::TestLog::EndMessage;
2663			status = false;
2664		}
2665		glGetIntegerv(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
2666		if (p < 2047)
2667		{
2668			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET is "
2669												<< p << " but must be at least 2047." << tcu::TestLog::EndMessage;
2670			status = false;
2671		}
2672		glGetIntegerv(GL_MAX_VERTEX_ATTRIB_STRIDE, &p);
2673		if (p < 2048)
2674		{
2675			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_STRIDE is " << p
2676												<< " but must be at least 2048." << tcu::TestLog::EndMessage;
2677			status = false;
2678		}
2679
2680		glBindVertexArray(m_vao);
2681
2682		glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &p);
2683		if (0 != p)
2684		{
2685			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_ELEMENT_ARRAY_BUFFER_BINDING is " << p
2686												<< " should be 0." << tcu::TestLog::EndMessage;
2687			status = false;
2688		}
2689		for (GLuint i = 0; i < 16; ++i)
2690		{
2691			VertexAttribState va(i);
2692			if (!va.stateVerify())
2693				status = false;
2694		}
2695		for (GLuint i = 0; i < 16; ++i)
2696		{
2697			VertexBindingState vb(i);
2698			if (!vb.stateVerify())
2699				status = false;
2700		}
2701		if (!status)
2702		{
2703			m_context.getTestContext().getLog()
2704				<< tcu::TestLog::Message << "Default state check failed." << tcu::TestLog::EndMessage;
2705			status = false;
2706		}
2707
2708		VertexAttribState va0(0);
2709		va0.array_size		 = 2;
2710		va0.array_type		 = GL_BYTE;
2711		va0.array_normalized = 1;
2712		va0.relative_offset  = 16;
2713		VertexBindingState vb0(0);
2714		glVertexAttribFormat(0, 2, GL_BYTE, GL_TRUE, 16);
2715		if (!va0.stateVerify() || !vb0.stateVerify())
2716		{
2717			m_context.getTestContext().getLog()
2718				<< tcu::TestLog::Message << "glVertexAttribFormat state change check failed."
2719				<< tcu::TestLog::EndMessage;
2720			status = false;
2721		}
2722
2723		VertexAttribState va2(2);
2724		va2.array_size		= 3;
2725		va2.array_type		= GL_DOUBLE;
2726		va2.array_long		= 1;
2727		va2.relative_offset = 512;
2728		VertexBindingState vb2(2);
2729		glVertexAttribLFormat(2, 3, GL_DOUBLE, 512);
2730		if (!va2.stateVerify() || !vb2.stateVerify())
2731		{
2732			m_context.getTestContext().getLog()
2733				<< tcu::TestLog::Message << "glVertexAttribIFormat state change check failed."
2734				<< tcu::TestLog::EndMessage;
2735			status = false;
2736		}
2737
2738		va0.array_buffer_binding = m_vbo[0];
2739		vb0.buffer				 = m_vbo[0];
2740		vb0.offset				 = 2048;
2741		vb0.stride				 = 128;
2742		glBindVertexBuffer(0, m_vbo[0], 2048, 128);
2743		if (!va0.stateVerify() || !vb0.stateVerify())
2744		{
2745			m_context.getTestContext().getLog()
2746				<< tcu::TestLog::Message << "glBindVertexBuffer state change check failed." << tcu::TestLog::EndMessage;
2747			status = false;
2748		}
2749
2750		va2.array_buffer_binding = m_vbo[2];
2751		vb2.buffer				 = m_vbo[2];
2752		vb2.offset				 = 64;
2753		vb2.stride				 = 256;
2754		glBindVertexBuffer(2, m_vbo[2], 64, 256);
2755		if (!va2.stateVerify() || !vb2.stateVerify())
2756		{
2757			m_context.getTestContext().getLog()
2758				<< tcu::TestLog::Message << "glBindVertexBuffer state change check failed." << tcu::TestLog::EndMessage;
2759			status = false;
2760		}
2761
2762		glVertexAttribBinding(2, 0);
2763		va2.binding				 = 0;
2764		va2.array_buffer_binding = m_vbo[0];
2765		if (!va0.stateVerify() || !vb0.stateVerify() || !va2.stateVerify() || !vb2.stateVerify())
2766		{
2767			m_context.getTestContext().getLog()
2768				<< tcu::TestLog::Message << "glVertexAttribBinding state change check failed."
2769				<< tcu::TestLog::EndMessage;
2770			status = false;
2771		}
2772
2773		VertexAttribState  va15(15);
2774		VertexBindingState vb15(15);
2775		glVertexAttribBinding(0, 15);
2776		va0.binding				 = 15;
2777		va0.array_buffer_binding = 0;
2778		if (!va0.stateVerify() || !vb0.stateVerify() || !va15.stateVerify() || !vb15.stateVerify())
2779		{
2780			m_context.getTestContext().getLog()
2781				<< tcu::TestLog::Message << "glVertexAttribBinding state change check failed."
2782				<< tcu::TestLog::EndMessage;
2783			status = false;
2784		}
2785
2786		glBindVertexBuffer(15, m_vbo[1], 16, 32);
2787		va0.array_buffer_binding  = m_vbo[1];
2788		va15.array_buffer_binding = m_vbo[1];
2789		vb15.buffer				  = m_vbo[1];
2790		vb15.offset				  = 16;
2791		vb15.stride				  = 32;
2792		if (!va0.stateVerify() || !vb0.stateVerify() || !va15.stateVerify() || !vb15.stateVerify())
2793		{
2794			m_context.getTestContext().getLog()
2795				<< tcu::TestLog::Message << "glBindVertexBuffer state change check failed." << tcu::TestLog::EndMessage;
2796			status = false;
2797		}
2798
2799		glVertexAttribLFormat(15, 1, GL_DOUBLE, 1024);
2800		va15.array_size		 = 1;
2801		va15.array_long		 = 1;
2802		va15.array_type		 = GL_DOUBLE;
2803		va15.relative_offset = 1024;
2804		if (!va0.stateVerify() || !vb0.stateVerify() || !va2.stateVerify() || !vb2.stateVerify() ||
2805			!va15.stateVerify() || !vb15.stateVerify())
2806		{
2807			m_context.getTestContext().getLog()
2808				<< tcu::TestLog::Message << "glVertexAttribFormat state change check failed."
2809				<< tcu::TestLog::EndMessage;
2810			status = false;
2811		}
2812
2813		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[2]);
2814		glVertexAttribPointer(0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 8, (void*)640);
2815		glBindBuffer(GL_ARRAY_BUFFER, 0);
2816		va0.array_size			 = 4;
2817		va0.array_type			 = GL_UNSIGNED_BYTE;
2818		va0.array_stride		 = 8;
2819		va0.array_pointer		 = 640;
2820		va0.relative_offset		 = 0;
2821		va0.array_normalized	 = 0;
2822		va0.binding				 = 0;
2823		va0.array_buffer_binding = m_vbo[2];
2824		vb0.buffer				 = m_vbo[2];
2825		vb0.offset				 = 640;
2826		vb0.stride				 = 8;
2827		va2.array_buffer_binding = m_vbo[2];
2828		if (!va0.stateVerify() || !vb0.stateVerify() || !va2.stateVerify() || !vb2.stateVerify() ||
2829			!va15.stateVerify() || !vb15.stateVerify())
2830		{
2831			m_context.getTestContext().getLog()
2832				<< tcu::TestLog::Message << "glVertexAttribPointer state change check failed."
2833				<< tcu::TestLog::EndMessage;
2834			status = false;
2835		}
2836
2837		glBindVertexBuffer(0, m_vbo[1], 80, 24);
2838		vb0.buffer				 = m_vbo[1];
2839		vb0.offset				 = 80;
2840		vb0.stride				 = 24;
2841		va2.array_buffer_binding = m_vbo[1];
2842		va0.array_buffer_binding = m_vbo[1];
2843		if (!va0.stateVerify() || !vb0.stateVerify() || !va2.stateVerify() || !vb2.stateVerify() ||
2844			!va15.stateVerify() || !vb15.stateVerify())
2845		{
2846			m_context.getTestContext().getLog()
2847				<< tcu::TestLog::Message << "glBindVertexBuffer state change check failed." << tcu::TestLog::EndMessage;
2848			status = false;
2849		}
2850
2851		if (status)
2852			return NO_ERROR;
2853		else
2854			return ERROR;
2855	}
2856};
2857
2858//=============================================================================
2859// 1.7 BasicState4
2860//-----------------------------------------------------------------------------
2861class BasicState4 : public VertexAttribBindingBase
2862{
2863	GLuint m_vao;
2864
2865	virtual long Setup()
2866	{
2867		glGenVertexArrays(1, &m_vao);
2868		return NO_ERROR;
2869	}
2870
2871	virtual long Cleanup()
2872	{
2873		glDeleteVertexArrays(1, &m_vao);
2874		return NO_ERROR;
2875	}
2876
2877	virtual long Run()
2878	{
2879		bool status = true;
2880		glBindVertexArray(m_vao);
2881
2882		for (GLuint i = 0; i < 16; ++i)
2883		{
2884			VertexAttribState  va(i);
2885			VertexBindingState vb(i);
2886			glVertexAttribDivisor(i, i + 7);
2887			va.array_divisor = i + 7;
2888			vb.divisor		 = i + 7;
2889			if (!va.stateVerify() || !vb.stateVerify())
2890			{
2891				m_context.getTestContext().getLog()
2892					<< tcu::TestLog::Message << "glVertexAttribDivisor state change check failed."
2893					<< tcu::TestLog::EndMessage;
2894				status = false;
2895			}
2896		}
2897		for (GLuint i = 0; i < 16; ++i)
2898		{
2899			VertexAttribState  va(i);
2900			VertexBindingState vb(i);
2901			glVertexBindingDivisor(i, i);
2902			va.array_divisor = i;
2903			vb.divisor		 = i;
2904			if (!va.stateVerify() || !vb.stateVerify())
2905			{
2906				m_context.getTestContext().getLog()
2907					<< tcu::TestLog::Message << "glVertexBindingDivisor state change check failed."
2908					<< tcu::TestLog::EndMessage;
2909				status = false;
2910			}
2911		}
2912
2913		glVertexAttribBinding(2, 5);
2914		VertexAttribState va5(5);
2915		va5.array_divisor = 5;
2916		VertexBindingState vb5(5);
2917		vb5.divisor = 5;
2918		VertexAttribState va2(2);
2919		va2.array_divisor = 5;
2920		VertexBindingState vb2(2);
2921		vb2.divisor = 2;
2922		va2.binding = 5;
2923		if (!va5.stateVerify() || !vb5.stateVerify() || !va2.stateVerify() || !vb2.stateVerify())
2924		{
2925			m_context.getTestContext().getLog()
2926				<< tcu::TestLog::Message << "glVertexAttribBinding state change check failed."
2927				<< tcu::TestLog::EndMessage;
2928			status = false;
2929		}
2930
2931		glVertexAttribDivisor(2, 23);
2932		va2.binding		  = 2;
2933		va2.array_divisor = 23;
2934		vb2.divisor		  = 23;
2935		if (!va5.stateVerify() || !vb5.stateVerify() || !va2.stateVerify() || !vb2.stateVerify())
2936		{
2937			m_context.getTestContext().getLog()
2938				<< tcu::TestLog::Message << "glVertexAttribDivisor state change check failed."
2939				<< tcu::TestLog::EndMessage;
2940			status = false;
2941		}
2942
2943		if (status)
2944			return NO_ERROR;
2945		else
2946			return ERROR;
2947	}
2948};
2949
2950//=============================================================================
2951// 2.1 AdvancedBindingUpdate
2952//-----------------------------------------------------------------------------
2953class AdvancedBindingUpdate : public VertexAttribBindingBase
2954{
2955	GLuint m_vao[2], m_vbo[2], m_ebo[2], m_vsp, m_fsp, m_ppo;
2956
2957	virtual long Setup()
2958	{
2959		glGenVertexArrays(2, m_vao);
2960		glGenBuffers(2, m_vbo);
2961		glGenBuffers(2, m_ebo);
2962		m_vsp = m_fsp = 0;
2963		glGenProgramPipelines(1, &m_ppo);
2964		return NO_ERROR;
2965	}
2966
2967	virtual long Cleanup()
2968	{
2969		glDeleteVertexArrays(2, m_vao);
2970		glDeleteBuffers(2, m_vbo);
2971		glDeleteBuffers(2, m_ebo);
2972		glDeleteProgram(m_vsp);
2973		glDeleteProgram(m_fsp);
2974		glDeleteProgramPipelines(1, &m_ppo);
2975		return NO_ERROR;
2976	}
2977
2978	virtual long Run()
2979	{
2980		const char* const glsl_vs =
2981			"#version 430 core" NL "layout(location = 0) in vec4 vs_in_position;" NL
2982			"layout(location = 1) in vec2 vs_in_color_rg;" NL "layout(location = 2) in float vs_in_color_b;" NL
2983			"layout(location = 3) in dvec3 vs_in_data0;" NL "layout(location = 4) in ivec2 vs_in_data1;" NL
2984			"out StageData {" NL "  vec2 color_rg;" NL "  float color_b;" NL "  dvec3 data0;" NL "  ivec2 data1;" NL
2985			"} vs_out;" NL "out gl_PerVertex {" NL "  vec4 gl_Position;" NL "};" NL "void main() {" NL
2986			"  vs_out.data1 = vs_in_data1;" NL "  vs_out.data0 = vs_in_data0;" NL "  vs_out.color_b = vs_in_color_b;" NL
2987			"  vs_out.color_rg = vs_in_color_rg;" NL "  gl_Position = vs_in_position;" NL "}";
2988		const char* const glsl_fs = "#version 430 core" NL "in StageData {" NL "  vec2 color_rg;" NL
2989									"  float color_b;" NL "  flat dvec3 data0;" NL "  flat ivec2 data1;" NL
2990									"} fs_in;" NL "layout(location = 0) out vec4 fs_out_color;" NL
2991									"uniform dvec3 g_expected_data0;" NL "uniform ivec2 g_expected_data1;" NL
2992									"void main() {" NL "  fs_out_color = vec4(fs_in.color_rg, fs_in.color_b, 1);" NL
2993									"  if (fs_in.data0 != g_expected_data0) fs_out_color = vec4(1);" NL
2994									"  if (fs_in.data1 != g_expected_data1) fs_out_color = vec4(1);" NL "}";
2995		m_vsp = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);
2996		m_fsp = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &glsl_fs);
2997		if (!CheckProgram(m_vsp) || !CheckProgram(m_fsp))
2998			return ERROR;
2999
3000		glUseProgramStages(m_ppo, GL_VERTEX_SHADER_BIT, m_vsp);
3001		glUseProgramStages(m_ppo, GL_FRAGMENT_SHADER_BIT, m_fsp);
3002
3003		const GLsizei  kStride[2] = { 52, 62 };
3004		const GLintptr kOffset[2] = { 0, 8 };
3005		/* Workaround for alignment issue that may result in bus error on some platforms */
3006		union {
3007			double d[3];
3008			char   c[3 * sizeof(double)];
3009		} u;
3010
3011		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
3012		{
3013			glBufferData(GL_ARRAY_BUFFER, kOffset[0] + 4 * kStride[0], NULL, GL_STATIC_DRAW);
3014			GLubyte* ptr = static_cast<GLubyte*>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
3015
3016			*reinterpret_cast<Vec2*>(&ptr[kOffset[0] + 0 * kStride[0]]) = Vec2(-1.0f, -1.0f);
3017			*reinterpret_cast<Vec2*>(&ptr[kOffset[0] + 1 * kStride[0]]) = Vec2(1.0f, -1.0f);
3018			*reinterpret_cast<Vec2*>(&ptr[kOffset[0] + 2 * kStride[0]]) = Vec2(1.0f, 1.0f);
3019			*reinterpret_cast<Vec2*>(&ptr[kOffset[0] + 3 * kStride[0]]) = Vec2(-1.0f, 1.0f);
3020
3021			for (int i = 0; i < 4; ++i)
3022			{
3023				*reinterpret_cast<Vec2*>(&ptr[kOffset[0] + 8 + i * kStride[0]])   = Vec2(0.0f, 1.0f);
3024				*reinterpret_cast<float*>(&ptr[kOffset[0] + 16 + i * kStride[0]]) = 0.0f;
3025				//*reinterpret_cast<DVec3 *>(&ptr[kOffset[0] + 20 + i * kStride[0]]) = DVec3(1.0, 2.0, 3.0);
3026
3027				memcpy(u.d, DVec3(1.0, 2.0, 3.0).m_data, 3 * sizeof(double));
3028				memcpy(&ptr[kOffset[0] + 20 + i * kStride[0]], u.c, 3 * sizeof(double));
3029				*reinterpret_cast<IVec2*>(&ptr[kOffset[0] + 44 + i * kStride[0]]) = IVec2(1, 2);
3030			}
3031			glUnmapBuffer(GL_ARRAY_BUFFER);
3032		}
3033		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
3034		{
3035			glBufferData(GL_ARRAY_BUFFER, kOffset[1] + 4 * kStride[1], NULL, GL_STATIC_DRAW);
3036			GLubyte* ptr = static_cast<GLubyte*>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
3037
3038			*reinterpret_cast<Vec2*>(&ptr[kOffset[1] + 0 * kStride[1]]) = Vec2(-1.0f, 1.0f);
3039			*reinterpret_cast<Vec2*>(&ptr[kOffset[1] + 1 * kStride[1]]) = Vec2(1.0f, 1.0f);
3040			*reinterpret_cast<Vec2*>(&ptr[kOffset[1] + 2 * kStride[1]]) = Vec2(1.0f, -1.0f);
3041			*reinterpret_cast<Vec2*>(&ptr[kOffset[1] + 3 * kStride[1]]) = Vec2(-1.0f, -1.0f);
3042
3043			for (int i = 0; i < 4; ++i)
3044			{
3045				*reinterpret_cast<Vec2*>(&ptr[kOffset[1] + 8 + i * kStride[1]])   = Vec2(0.0f, 0.0f);
3046				*reinterpret_cast<float*>(&ptr[kOffset[1] + 16 + i * kStride[1]]) = 1.0f;
3047				//*reinterpret_cast<DVec3 *>(&ptr[kOffset[1] + 20 + i * kStride[1]]) = DVec3(4.0, 5.0, 6.0);
3048
3049				memcpy(u.d, DVec3(4.0, 5.0, 6.0).m_data, 3 * sizeof(double));
3050				memcpy(&ptr[kOffset[1] + 20 + i * kStride[1]], u.c, 3 * sizeof(double));
3051				*reinterpret_cast<IVec2*>(&ptr[kOffset[1] + 44 + i * kStride[1]]) = IVec2(3, 4);
3052			}
3053			glUnmapBuffer(GL_ARRAY_BUFFER);
3054		}
3055		glBindBuffer(GL_ARRAY_BUFFER, 0);
3056
3057		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[0]);
3058		{
3059			GLushort data[4] = { 0, 1, 3, 2 };
3060			glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
3061		}
3062		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[1]);
3063		{
3064			GLuint data[4] = { 3, 2, 0, 1 };
3065			glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
3066		}
3067		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3068
3069		glBindVertexArray(m_vao[0]);
3070		glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
3071		glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, 8);
3072		glVertexAttribFormat(2, 1, GL_FLOAT, GL_FALSE, 16);
3073		glVertexAttribLFormat(3, 3, GL_DOUBLE, 20);
3074		glVertexAttribIFormat(4, 2, GL_INT, 44);
3075
3076		for (GLuint i = 0; i < 5; ++i)
3077		{
3078			glVertexAttribBinding(i, 0);
3079			glEnableVertexAttribArray(i);
3080		}
3081		glBindVertexArray(m_vao[1]);
3082		glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
3083		glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, 8);
3084		glVertexAttribFormat(2, 1, GL_FLOAT, GL_FALSE, 16);
3085		glVertexAttribLFormat(3, 3, GL_DOUBLE, 20);
3086		glVertexAttribIFormat(4, 2, GL_INT, 44);
3087		glVertexAttribBinding(0, 1);
3088		glVertexAttribBinding(1, 8);
3089		glVertexAttribBinding(2, 1);
3090		glVertexAttribBinding(3, 1);
3091		glVertexAttribBinding(4, 8);
3092		glEnableVertexAttribArray(0);
3093		glEnableVertexAttribArray(1);
3094		glEnableVertexAttribArray(2);
3095		glEnableVertexAttribArray(3);
3096		glEnableVertexAttribArray(4);
3097		glBindVertexBuffer(1, m_vbo[1], kOffset[1], kStride[1]);
3098		glBindVertexBuffer(8, m_vbo[0], kOffset[0], kStride[0]);
3099		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[1]);
3100		glBindVertexArray(0);
3101
3102		glClear(GL_COLOR_BUFFER_BIT);
3103		glBindProgramPipeline(m_ppo);
3104		glBindVertexArray(m_vao[0]);
3105
3106		glProgramUniform3d(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data0"), 1.0, 2.0, 3.0);
3107		glProgramUniform2i(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data1"), 1, 2);
3108
3109		glBindVertexBuffer(0, m_vbo[0], kOffset[0], kStride[0]);
3110		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[0]);
3111		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1, 0, 0);
3112
3113		bool			  status = true;
3114		std::vector<Vec3> fb(getWindowWidth() * getWindowHeight());
3115		glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3116		if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 1, 0)))
3117			status = false;
3118		if (!status)
3119			return ERROR;
3120
3121		glProgramUniform3d(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data0"), 4.0, 5.0, 6.0);
3122		glProgramUniform2i(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data1"), 3, 4);
3123
3124		glBindVertexBuffer(0, m_vbo[1], kOffset[1], kStride[1]);
3125		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[1]);
3126		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0, 1, 0, 0);
3127
3128		glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3129		if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 0, 1)))
3130			status = false;
3131		if (!status)
3132			return ERROR;
3133
3134		glBindVertexBuffer(0, 0, 0, 0);
3135
3136		glProgramUniform3d(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data0"), 1.0, 2.0, 3.0);
3137		glProgramUniform2i(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data1"), 1, 2);
3138
3139		for (GLuint i = 0; i < 5; ++i)
3140			glVertexAttribBinding(i, 15);
3141		glBindVertexBuffer(15, m_vbo[0], kOffset[0], kStride[0]);
3142		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[0]);
3143		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1, 0, 0);
3144
3145		glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3146		if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 1, 0)))
3147			status = false;
3148		if (!status)
3149			return ERROR;
3150
3151		glBindVertexBuffer(15, 0, 0, 0);
3152
3153		glProgramUniform3d(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data0"), 1.0, 2.0, 3.0);
3154		glProgramUniform2i(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data1"), 3, 4);
3155
3156		glBindVertexBuffer(7, m_vbo[0], kOffset[0], kStride[0]);
3157		glBindVertexBuffer(12, m_vbo[1], kOffset[1], kStride[1]);
3158		glVertexAttribBinding(0, 7);
3159		glVertexAttribBinding(1, 12);
3160		glVertexAttribBinding(2, 12);
3161		glVertexAttribBinding(3, 7);
3162		glVertexAttribBinding(4, 12);
3163		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[0]);
3164		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1, 0, 0);
3165
3166		glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3167		if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 0, 1)))
3168			status = false;
3169		if (!status)
3170			return ERROR;
3171
3172		glClear(GL_COLOR_BUFFER_BIT);
3173		glProgramUniform2i(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data1"), 0, 0);
3174		glDisableVertexAttribArray(4);
3175		glVertexAttribI4i(4, 0, 0, 0, 0);
3176		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1, 0, 0);
3177
3178		glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3179		if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 0, 1)))
3180			status = false;
3181		if (!status)
3182			return ERROR;
3183
3184		glProgramUniform3d(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data0"), 4.0, 5.0, 6.0);
3185		glProgramUniform2i(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data1"), 1, 2);
3186
3187		glBindVertexArray(m_vao[1]);
3188		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0, 1, 0, 0);
3189
3190		glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3191		if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0.0f, 1.0f, 1.0f)))
3192			status = false;
3193		if (!status)
3194			return ERROR;
3195
3196		return NO_ERROR;
3197	}
3198};
3199
3200//=============================================================================
3201// 2.2 AdvancedInstancing
3202//-----------------------------------------------------------------------------
3203class AdvancedInstancing : public VertexAttribBindingBase
3204{
3205	GLuint m_pipeline;
3206	GLuint m_vsp, m_fsp;
3207	GLuint m_vertex_array[2];
3208	GLuint m_vertex_buffer;
3209	GLuint m_index_buffer;
3210	GLuint m_object_id_buffer;
3211	GLuint m_transform_texture, m_transform_buffer;
3212
3213	virtual long Setup()
3214	{
3215		glGenProgramPipelines(1, &m_pipeline);
3216		m_vsp = m_fsp = 0;
3217		glGenVertexArrays(2, m_vertex_array);
3218		glGenBuffers(1, &m_vertex_buffer);
3219		glGenBuffers(1, &m_index_buffer);
3220		glGenBuffers(1, &m_object_id_buffer);
3221		glGenBuffers(1, &m_transform_buffer);
3222		glGenTextures(1, &m_transform_texture);
3223		return NO_ERROR;
3224	}
3225
3226	virtual long Cleanup()
3227	{
3228		glDeleteProgramPipelines(1, &m_pipeline);
3229		glDeleteProgram(m_vsp);
3230		glDeleteProgram(m_fsp);
3231		glDeleteVertexArrays(2, m_vertex_array);
3232		glDeleteBuffers(1, &m_vertex_buffer);
3233		glDeleteBuffers(1, &m_index_buffer);
3234		glDeleteBuffers(1, &m_object_id_buffer);
3235		glDeleteBuffers(1, &m_transform_buffer);
3236		glDeleteTextures(1, &m_transform_texture);
3237		return NO_ERROR;
3238	}
3239
3240	virtual long Run()
3241	{
3242		const char* const glsl_ver = "#version 430 core\n";
3243		const char* const glsl =
3244			NL "#if defined(VS_PASS_THROUGH)" NL "layout(location = 0) in vec4 vs_in_position;" NL
3245			   "layout(location = 1) in vec3 vs_in_normal;" NL "layout(location = 2) in int vs_in_object_id;" NL
3246			   "out StageData {" NL "  float f;" NL "  vec3 normal;" NL "  int object_id;" NL "} vs_out;" NL
3247			   "out gl_PerVertex {" NL "  vec4 gl_Position;" NL "};" NL
3248			   "layout(binding = 0) uniform samplerBuffer g_transform_buffer;" NL "mat4 GetTransformMatrix(int id) {" NL
3249			   "  return mat4(texelFetch(g_transform_buffer, id * 4)," NL
3250			   "              texelFetch(g_transform_buffer, id * 4 + 1)," NL
3251			   "              texelFetch(g_transform_buffer, id * 4 + 2)," NL
3252			   "              texelFetch(g_transform_buffer, id * 4 + 3));" NL "}" NL "void main() {" NL
3253			   "  gl_Position = GetTransformMatrix(vs_in_object_id) * vs_in_position;" NL "  vs_out.f = 123.0;" NL
3254			   "  vs_out.normal = vs_in_normal;" NL "  vs_out.object_id = vs_in_object_id;" NL "}" NL
3255			   "#elif defined(FS_SOLID_COLOR)" NL "in StageData {" NL "  float f;" NL "  vec3 normal;" NL
3256			   "  flat int object_id;" NL "} fs_in;" NL "layout(location = 0) out vec4 g_color;" NL "void main() {" NL
3257			   "  if (fs_in.object_id == 0) g_color = vec4(1, 0, 0, 1);" NL
3258			   "  else if (fs_in.object_id == 1) g_color = vec4(0, 1, 0, 1);" NL
3259			   "  else if (fs_in.object_id == 2) g_color = vec4(0, 0, 1, 1);" NL
3260			   "  else if (fs_in.object_id == 3) g_color = vec4(1, 1, 0, 1);" NL "}" NL "#endif";
3261		/* VS_PASS_THROUGH */
3262		{
3263			const char* const src[] = { glsl_ver, "#define VS_PASS_THROUGH\n", glsl };
3264			m_vsp					= glCreateShaderProgramv(GL_VERTEX_SHADER, sizeof(src) / sizeof(src[0]), src);
3265		}
3266		/* FS_SOLID_COLOR */
3267		{
3268			const char* const src[] = { glsl_ver, "#define FS_SOLID_COLOR\n", glsl };
3269			m_fsp					= glCreateShaderProgramv(GL_FRAGMENT_SHADER, sizeof(src) / sizeof(src[0]), src);
3270		}
3271		if (!CheckProgram(m_vsp))
3272			return ERROR;
3273		if (!CheckProgram(m_fsp))
3274			return ERROR;
3275
3276		glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_vsp);
3277		glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, m_fsp);
3278
3279		{
3280			const float data[] = { -0.5f, -0.5f, 1.0f,  0.0f, 0.0f,  1.5f,  -0.5f, 1.0f, 0.0f,  0.0f,  -0.5f, 1.5f,
3281								   1.0f,  0.0f,  0.0f,  1.5f, 1.5f,  1.0f,  0.0f,  0.0f, -1.5f, -0.5f, 0.0f,  1.0f,
3282								   0.0f,  0.5f,  -0.5f, 0.0f, 1.0f,  0.0f,  -1.5f, 1.5f, 0.0f,  1.0f,  0.0f,  0.5f,
3283								   1.5f,  0.0f,  1.0f,  0.0f, -1.5f, -1.5f, 0.0f,  0.0f, 1.0f,  0.5f,  -1.5f, 0.0f,
3284								   0.0f,  1.0f,  -1.5f, 0.5f, 0.0f,  0.0f,  1.0f,  0.5f, 0.5f,  0.0f,  0.0f,  1.0f,
3285								   -0.5f, -1.5f, 1.0f,  1.0f, 0.0f,  1.5f,  -1.5f, 1.0f, 1.0f,  0.0f,  -0.5f, 0.5f,
3286								   1.0f,  1.0f,  0.0f,  1.5f, 0.5f,  1.0f,  1.0f,  0.0f };
3287			glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
3288			glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
3289			glBindBuffer(GL_ARRAY_BUFFER, 0);
3290		}
3291		{
3292			const unsigned int data[] = { 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 };
3293			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer);
3294			glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
3295			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3296		}
3297		{
3298			const int data[] = { 0, 1, 2, 3 };
3299			glBindBuffer(GL_ARRAY_BUFFER, m_object_id_buffer);
3300			glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
3301			glBindBuffer(GL_ARRAY_BUFFER, 0);
3302		}
3303		glBindVertexArray(m_vertex_array[0]);
3304		glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
3305		glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 8);
3306		glVertexAttribIFormat(2, 1, GL_INT, 0);
3307		glEnableVertexAttribArray(0);
3308		glEnableVertexAttribArray(1);
3309		glEnableVertexAttribArray(2);
3310		glVertexAttribBinding(1, 0);
3311		glBindVertexBuffer(0, m_vertex_buffer, 0, 20);
3312		glBindVertexBuffer(2, m_object_id_buffer, 0, 4);
3313		glVertexBindingDivisor(2, 1);
3314		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer);
3315		glBindVertexArray(m_vertex_array[1]);
3316		glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
3317		glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
3318		glVertexAttribIFormat(2, 1, GL_INT, 0);
3319		glEnableVertexAttribArray(0);
3320		glEnableVertexAttribArray(1);
3321		glEnableVertexAttribArray(2);
3322		glVertexAttribBinding(2, 13);
3323		glVertexAttribBinding(1, 14);
3324		glVertexAttribBinding(0, 15);
3325		glBindVertexBuffer(15, m_vertex_buffer, 0, 20);
3326		glBindVertexBuffer(14, m_vertex_buffer, 8, 20);
3327		glBindVertexBuffer(13, m_object_id_buffer, 0, 4);
3328		glVertexBindingDivisor(13, 1);
3329		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer);
3330		glBindVertexArray(0);
3331
3332		{
3333			const Mat4 data[] = { Translation(-0.5f, -0.5f, 0.0f), Translation(0.5f, -0.5f, 0.0f),
3334								  Translation(0.5f, 0.5f, 0.0f), Translation(-0.5f, 0.5f, 0.0f) };
3335			glBindBuffer(GL_TEXTURE_BUFFER, m_transform_buffer);
3336			glBufferData(GL_TEXTURE_BUFFER, sizeof(data), &data, GL_DYNAMIC_DRAW);
3337			glBindBuffer(GL_TEXTURE_BUFFER, 0);
3338		}
3339		glBindTexture(GL_TEXTURE_BUFFER, m_transform_texture);
3340		glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_transform_buffer);
3341		glBindTexture(GL_TEXTURE_BUFFER, 0);
3342
3343		glClear(GL_COLOR_BUFFER_BIT);
3344		glBindProgramPipeline(m_pipeline);
3345		glActiveTexture(GL_TEXTURE0);
3346		glBindTexture(GL_TEXTURE_BUFFER, m_transform_texture);
3347		glBindVertexArray(m_vertex_array[0]);
3348
3349		std::vector<Vec3> fb(getWindowWidth() * getWindowHeight());
3350		bool			  status = true;
3351
3352		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0, 1, 0, 0);
3353		glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3354		if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(1, 0, 0)))
3355			status = false;
3356		if (!status)
3357			return ERROR;
3358
3359		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT,
3360													  (void*)(4 * sizeof(unsigned int)), 1, 4, 1);
3361		glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3362		if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 1, 0)))
3363			status = false;
3364		if (!status)
3365			return ERROR;
3366
3367		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT,
3368													  (void*)(8 * sizeof(unsigned int)), 1, 8, 2);
3369		glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3370		if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 0, 1)))
3371			status = false;
3372		if (!status)
3373			return ERROR;
3374
3375		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT,
3376													  (void*)(12 * sizeof(unsigned int)), 1, 12, 3);
3377		glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3378		if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(1, 1, 0)))
3379			status = false;
3380		if (!status)
3381			return ERROR;
3382
3383		glBindVertexArray(m_vertex_array[1]);
3384
3385		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT,
3386													  (void*)(8 * sizeof(unsigned int)), 1, 8, 2);
3387		glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3388		if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 0, 1)))
3389			status = false;
3390		if (!status)
3391			return ERROR;
3392
3393		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0, 1, 0, 0);
3394		glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3395		if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(1, 0, 0)))
3396			status = false;
3397		if (!status)
3398			return ERROR;
3399
3400		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT,
3401													  (void*)(4 * sizeof(unsigned int)), 1, 4, 1);
3402		glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3403		if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 1, 0)))
3404			status = false;
3405		if (!status)
3406			return ERROR;
3407
3408		glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT,
3409													  (void*)(12 * sizeof(unsigned int)), 1, 12, 3);
3410		glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3411		if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(1, 1, 0)))
3412			status = false;
3413		if (!status)
3414			return ERROR;
3415
3416		return NO_ERROR;
3417	}
3418};
3419
3420//=============================================================================
3421// 2.3 AdvancedIterations
3422//-----------------------------------------------------------------------------
3423class AdvancedIterations : public VertexAttribBindingBase
3424{
3425	GLuint m_po, m_vao[2], m_xfo[2], m_buffer[2];
3426
3427	virtual long Setup()
3428	{
3429		m_po = 0;
3430		glGenVertexArrays(2, m_vao);
3431		glGenTransformFeedbacks(2, m_xfo);
3432		glGenBuffers(2, m_buffer);
3433		return NO_ERROR;
3434	}
3435
3436	virtual long Cleanup()
3437	{
3438		glDisable(GL_RASTERIZER_DISCARD);
3439		glUseProgram(0);
3440		glDeleteProgram(m_po);
3441		glDeleteVertexArrays(2, m_vao);
3442		glDeleteTransformFeedbacks(2, m_xfo);
3443		glDeleteBuffers(2, m_buffer);
3444		return NO_ERROR;
3445	}
3446
3447	virtual long Run()
3448	{
3449		const char* const glsl_vs =
3450			"#version 430 core" NL "in ivec4 vs_in_data;" NL "out StageData {" NL "  ivec4 data;" NL "} vs_out;" NL
3451			"void main() {" NL "  vs_out.data = vs_in_data + 1;" NL "}";
3452
3453		m_po = glCreateProgram();
3454		{
3455			const GLuint sh = glCreateShader(GL_VERTEX_SHADER);
3456			glShaderSource(sh, 1, &glsl_vs, NULL);
3457			glCompileShader(sh);
3458			glAttachShader(m_po, sh);
3459			glDeleteShader(sh);
3460		}
3461		if (!RelinkProgram(1))
3462			return ERROR;
3463
3464		glBindBuffer(GL_ARRAY_BUFFER, m_buffer[0]);
3465		IVec4 zero(0);
3466		glBufferData(GL_ARRAY_BUFFER, 16, &zero, GL_STATIC_DRAW);
3467		glBindBuffer(GL_ARRAY_BUFFER, 0);
3468
3469		glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer[1]);
3470		glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, &zero, GL_DYNAMIC_READ);
3471		glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
3472
3473		glBindVertexArray(m_vao[0]);
3474		glVertexAttribIFormat(1, 4, GL_INT, 0);
3475		glEnableVertexAttribArray(1);
3476		glBindVertexBuffer(1, m_buffer[0], 0, 16);
3477		glBindVertexArray(m_vao[1]);
3478		glVertexAttribIFormat(1, 4, GL_INT, 0);
3479		glEnableVertexAttribArray(1);
3480		glBindVertexBuffer(1, m_buffer[1], 0, 16);
3481		glBindVertexArray(0);
3482
3483		glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfo[0]);
3484		glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer[1]);
3485		glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfo[1]);
3486		glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer[0]);
3487		glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
3488
3489		glEnable(GL_RASTERIZER_DISCARD);
3490		glUseProgram(m_po);
3491
3492		for (int i = 0; i < 10; ++i)
3493		{
3494			glBindVertexArray(m_vao[i % 2]);
3495			glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfo[i % 2]);
3496			glBeginTransformFeedback(GL_POINTS);
3497			glDrawArrays(GL_POINTS, 0, 1);
3498			glEndTransformFeedback();
3499		}
3500		{
3501			IVec4 data;
3502			glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer[0]);
3503			glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 16, &data[0]);
3504			if (!IsEqual(data, IVec4(10)))
3505			{
3506				m_context.getTestContext().getLog()
3507					<< tcu::TestLog::Message << "Data is: " << data[0] << " " << data[1] << " " << data[2] << " "
3508					<< data[3] << ", data should be: 10 10 10 10." << tcu::TestLog::EndMessage;
3509				return ERROR;
3510			}
3511		}
3512
3513		if (!RelinkProgram(5))
3514			return ERROR;
3515
3516		glBindVertexArray(m_vao[0]);
3517		glDisableVertexAttribArray(1);
3518		glBindVertexBuffer(1, 0, 0, 0);
3519		glVertexAttribIFormat(5, 4, GL_INT, 0);
3520		glEnableVertexAttribArray(5);
3521		glBindVertexBuffer(5, m_buffer[0], 0, 16);
3522		glBindVertexArray(m_vao[1]);
3523		glDisableVertexAttribArray(1);
3524		glBindVertexBuffer(1, 0, 0, 0);
3525		glVertexAttribIFormat(5, 4, GL_INT, 0);
3526		glEnableVertexAttribArray(5);
3527		glBindVertexBuffer(7, m_buffer[1], 0, 16);
3528		glVertexAttribBinding(5, 7);
3529		glBindVertexArray(0);
3530
3531		for (int i = 0; i < 10; ++i)
3532		{
3533			glBindVertexArray(m_vao[i % 2]);
3534			glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfo[i % 2]);
3535			glBeginTransformFeedback(GL_POINTS);
3536			glDrawArrays(GL_POINTS, 0, 1);
3537			glEndTransformFeedback();
3538		}
3539		{
3540			IVec4 data;
3541			glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer[0]);
3542			glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 16, &data[0]);
3543			if (!IsEqual(data, IVec4(20)))
3544			{
3545				m_context.getTestContext().getLog()
3546					<< tcu::TestLog::Message << "Data is: " << data[0] << " " << data[1] << " " << data[2] << " "
3547					<< data[3] << ", data should be: 20 20 20 20." << tcu::TestLog::EndMessage;
3548				return ERROR;
3549			}
3550		}
3551
3552		if (!RelinkProgram(11))
3553			return ERROR;
3554		glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
3555		glBindVertexArray(m_vao[0]);
3556		glDisableVertexAttribArray(5);
3557		glBindVertexBuffer(5, 0, 0, 0);
3558		glVertexAttribIFormat(11, 4, GL_INT, 0);
3559		glEnableVertexAttribArray(11);
3560		for (int i = 0; i < 10; ++i)
3561		{
3562			glBindVertexBuffer(11, m_buffer[i % 2], 0, 16);
3563			glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer[(i + 1) % 2]);
3564			glBeginTransformFeedback(GL_POINTS);
3565			glDrawArrays(GL_POINTS, 0, 1);
3566			glEndTransformFeedback();
3567		}
3568		{
3569			IVec4 data;
3570			glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer[0]);
3571			glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 16, &data[0]);
3572			if (!IsEqual(data, IVec4(30)))
3573			{
3574				m_context.getTestContext().getLog()
3575					<< tcu::TestLog::Message << "Data is: " << data[0] << " " << data[1] << " " << data[2] << " "
3576					<< data[3] << ", data should be: 30 30 30 30." << tcu::TestLog::EndMessage;
3577				return ERROR;
3578			}
3579		}
3580
3581		return NO_ERROR;
3582	}
3583
3584	bool RelinkProgram(GLuint index)
3585	{
3586		glBindAttribLocation(m_po, index, "vs_in_data");
3587		{
3588			const GLchar* const v[1] = { "StageData.data" };
3589			glTransformFeedbackVaryings(m_po, 1, v, GL_INTERLEAVED_ATTRIBS);
3590		}
3591		glLinkProgram(m_po);
3592		if (!CheckProgram(m_po))
3593			return false;
3594		return true;
3595	}
3596};
3597
3598//=============================================================================
3599// 2.4 AdvancedLargeStrideAndOffsetsNewAndLegacyAPI
3600//-----------------------------------------------------------------------------
3601class AdvancedLargeStrideAndOffsetsNewAndLegacyAPI : public VertexAttribBindingBase
3602{
3603	GLuint m_vsp, m_ppo, m_ssbo, m_vao, m_vbo;
3604
3605	virtual long Setup()
3606	{
3607		m_vsp = 0;
3608		glGenProgramPipelines(1, &m_ppo);
3609		glGenBuffers(1, &m_ssbo);
3610		glGenVertexArrays(1, &m_vao);
3611		glGenBuffers(1, &m_vbo);
3612		return NO_ERROR;
3613	}
3614
3615	virtual long Cleanup()
3616	{
3617		glDisable(GL_RASTERIZER_DISCARD);
3618		glDeleteProgram(m_vsp);
3619		glDeleteProgramPipelines(1, &m_ppo);
3620		glDeleteBuffers(1, &m_ssbo);
3621		glDeleteVertexArrays(1, &m_vao);
3622		glDeleteBuffers(1, &m_vbo);
3623		return NO_ERROR;
3624	}
3625
3626	virtual long Run()
3627	{
3628		const char* const glsl_vs =
3629			"#version 430 core" NL "layout(location = 0) in vec2 vs_in_attrib0;" NL
3630			"layout(location = 4) in ivec2 vs_in_attrib1;" NL "layout(location = 8) in uvec2 vs_in_attrib2;" NL
3631			"layout(location = 15) in float vs_in_attrib3;" NL "layout(std430, binding = 1) buffer Output {" NL
3632			"  vec2 attrib0[4];" NL "  ivec2 attrib1[4];" NL "  uvec2 attrib2[4];" NL "  float attrib3[4];" NL
3633			"} g_output;" NL "void main() {" NL
3634			"  g_output.attrib0[2 * gl_InstanceID + gl_VertexID] = vs_in_attrib0;" NL
3635			"  g_output.attrib1[2 * gl_InstanceID + gl_VertexID] = vs_in_attrib1;" NL
3636			"  g_output.attrib2[2 * gl_InstanceID + gl_VertexID] = vs_in_attrib2;" NL
3637			"  g_output.attrib3[2 * gl_InstanceID + gl_VertexID] = vs_in_attrib3;" NL "}";
3638		m_vsp = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);
3639		if (!CheckProgram(m_vsp))
3640			return ERROR;
3641		glUseProgramStages(m_ppo, GL_VERTEX_SHADER_BIT, m_vsp);
3642
3643		{
3644			glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
3645			glBufferData(GL_ARRAY_BUFFER, 100000, NULL, GL_STATIC_DRAW);
3646			GLubyte* ptr = static_cast<GLubyte*>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
3647
3648			*reinterpret_cast<Vec2*>(&ptr[16 + 0 * 2048])	= Vec2(1.0f, 2.0f);
3649			*reinterpret_cast<Vec2*>(&ptr[16 + 1 * 2048])	= Vec2(3.0f, 4.0f);
3650			*reinterpret_cast<IVec2*>(&ptr[128 + 0 * 2048])  = IVec2(5, 6);
3651			*reinterpret_cast<IVec2*>(&ptr[128 + 1 * 2048])  = IVec2(7, 8);
3652			*reinterpret_cast<UVec2*>(&ptr[1024 + 0 * 2048]) = UVec2(9, 10);
3653			*reinterpret_cast<UVec2*>(&ptr[1024 + 1 * 2048]) = UVec2(11, 12);
3654			*reinterpret_cast<float*>(&ptr[2032 + 0 * 2048]) = 13.0f;
3655			*reinterpret_cast<float*>(&ptr[2032 + 1 * 2048]) = 14.0f;
3656
3657			glUnmapBuffer(GL_ARRAY_BUFFER);
3658			glBindBuffer(GL_ARRAY_BUFFER, 0);
3659		}
3660		glBindVertexArray(m_vao);
3661		glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 16);
3662		glVertexAttribIFormat(8, 2, GL_UNSIGNED_INT, 1024);
3663		glVertexAttribFormat(15, 1, GL_FLOAT, GL_FALSE, 2032);
3664		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
3665		glVertexAttribIPointer(4, 2, GL_INT, 2048, reinterpret_cast<void*>(128));
3666		glBindBuffer(GL_ARRAY_BUFFER, 0);
3667		glVertexAttribBinding(8, 3);
3668		glVertexAttribBinding(15, 3);
3669		glBindVertexBuffer(0, m_vbo, 0, 2048);
3670		glBindVertexBuffer(3, m_vbo, 0, 2048);
3671		glEnableVertexAttribArray(0);
3672		glEnableVertexAttribArray(4);
3673		glEnableVertexAttribArray(8);
3674		glEnableVertexAttribArray(15);
3675		glBindVertexArray(0);
3676
3677		std::vector<GLubyte> data((sizeof(Vec2) + sizeof(IVec2) + sizeof(UVec2) + sizeof(float)) * 4, 0xff);
3678		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_ssbo);
3679		glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)data.size(), &data[0], GL_DYNAMIC_DRAW);
3680
3681		glEnable(GL_RASTERIZER_DISCARD);
3682		glBindProgramPipeline(m_ppo);
3683		glBindVertexArray(m_vao);
3684		glDrawArraysInstanced(GL_POINTS, 0, 2, 2);
3685
3686		{
3687			glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_ssbo);
3688			GLubyte* ptr = static_cast<GLubyte*>(glMapBuffer(GL_SHADER_STORAGE_BUFFER, GL_READ_ONLY));
3689
3690			Vec2 i0_v0_a0 = *reinterpret_cast<Vec2*>(&ptr[0]);
3691			Vec2 i0_v1_a0 = *reinterpret_cast<Vec2*>(&ptr[8]);
3692			Vec2 i1_v0_a0 = *reinterpret_cast<Vec2*>(&ptr[16]);
3693			Vec2 i1_v1_a0 = *reinterpret_cast<Vec2*>(&ptr[24]);
3694
3695			if (!IsEqual(i0_v0_a0, Vec2(1.0f, 2.0f)))
3696				return ERROR;
3697			if (!IsEqual(i0_v1_a0, Vec2(3.0f, 4.0f)))
3698				return ERROR;
3699			if (!IsEqual(i1_v0_a0, Vec2(1.0f, 2.0f)))
3700				return ERROR;
3701			if (!IsEqual(i1_v1_a0, Vec2(3.0f, 4.0f)))
3702				return ERROR;
3703
3704			IVec2 i0_v0_a1 = *reinterpret_cast<IVec2*>(&ptr[32]);
3705			IVec2 i0_v1_a1 = *reinterpret_cast<IVec2*>(&ptr[40]);
3706			IVec2 i1_v0_a1 = *reinterpret_cast<IVec2*>(&ptr[48]);
3707			IVec2 i1_v1_a1 = *reinterpret_cast<IVec2*>(&ptr[56]);
3708
3709			if (!IsEqual(i0_v0_a1, IVec2(5, 6)))
3710				return ERROR;
3711			if (!IsEqual(i0_v1_a1, IVec2(7, 8)))
3712				return ERROR;
3713			if (!IsEqual(i1_v0_a1, IVec2(5, 6)))
3714				return ERROR;
3715			if (!IsEqual(i1_v1_a1, IVec2(7, 8)))
3716				return ERROR;
3717
3718			UVec2 i0_v0_a2 = *reinterpret_cast<UVec2*>(&ptr[64]);
3719			UVec2 i0_v1_a2 = *reinterpret_cast<UVec2*>(&ptr[72]);
3720			UVec2 i1_v0_a2 = *reinterpret_cast<UVec2*>(&ptr[80]);
3721			UVec2 i1_v1_a2 = *reinterpret_cast<UVec2*>(&ptr[88]);
3722
3723			if (!IsEqual(i0_v0_a2, UVec2(9, 10)))
3724				return ERROR;
3725			if (!IsEqual(i0_v1_a2, UVec2(11, 12)))
3726				return ERROR;
3727			if (!IsEqual(i1_v0_a2, UVec2(9, 10)))
3728				return ERROR;
3729			if (!IsEqual(i1_v1_a2, UVec2(11, 12)))
3730				return ERROR;
3731
3732			float i0_v0_a3 = *reinterpret_cast<float*>(&ptr[96]);
3733			float i0_v1_a3 = *reinterpret_cast<float*>(&ptr[100]);
3734			float i1_v0_a3 = *reinterpret_cast<float*>(&ptr[104]);
3735			float i1_v1_a3 = *reinterpret_cast<float*>(&ptr[108]);
3736
3737			if (i0_v0_a3 != 13.0f)
3738				return ERROR;
3739			if (i0_v1_a3 != 14.0f)
3740				return ERROR;
3741			if (i1_v0_a3 != 13.0f)
3742				return ERROR;
3743			if (i1_v1_a3 != 14.0f)
3744				return ERROR;
3745			glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
3746		}
3747		return NO_ERROR;
3748	}
3749};
3750
3751//=============================================================================
3752// 4.1 NegativeBindVertexBuffer
3753//-----------------------------------------------------------------------------
3754class NegativeBindVertexBuffer : public VertexAttribBindingBase
3755{
3756	GLuint m_vao, m_vbo;
3757
3758	virtual long Setup()
3759	{
3760		glGenVertexArrays(1, &m_vao);
3761		glGenBuffers(1, &m_vbo);
3762		return NO_ERROR;
3763	}
3764
3765	virtual long Cleanup()
3766	{
3767		glDeleteVertexArrays(1, &m_vao);
3768		glDeleteBuffers(1, &m_vbo);
3769		return NO_ERROR;
3770	}
3771
3772	virtual long Run()
3773	{
3774		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
3775		glBufferData(GL_ARRAY_BUFFER, 1000, NULL, GL_STATIC_DRAW);
3776		glBindBuffer(GL_ARRAY_BUFFER, 0);
3777
3778		glBindVertexArray(m_vao);
3779
3780		glBindVertexBuffer(0, 1234, 0, 12);
3781		if (glGetError() != GL_INVALID_OPERATION)
3782		{
3783			m_context.getTestContext().getLog()
3784				<< tcu::TestLog::Message << "INVALID_OPERATION should be generated." << tcu::TestLog::EndMessage;
3785			return ERROR;
3786		}
3787
3788		GLint p;
3789		glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &p);
3790		glBindVertexBuffer(p + 1, m_vbo, 0, 12);
3791		if (glGetError() != GL_INVALID_VALUE)
3792		{
3793			m_context.getTestContext().getLog()
3794				<< tcu::TestLog::Message << "INVALID_VALUE should be generated." << tcu::TestLog::EndMessage;
3795			return ERROR;
3796		}
3797
3798		glBindVertexBuffer(0, m_vbo, -10, 12);
3799		if (glGetError() != GL_INVALID_VALUE)
3800		{
3801			m_context.getTestContext().getLog()
3802				<< tcu::TestLog::Message << "INVALID_VALUE should be generated." << tcu::TestLog::EndMessage;
3803			return ERROR;
3804		}
3805		glBindVertexBuffer(0, m_vbo, 0, -12);
3806		if (glGetError() != GL_INVALID_VALUE)
3807		{
3808			m_context.getTestContext().getLog()
3809				<< tcu::TestLog::Message << "INVALID_VALUE should be generated." << tcu::TestLog::EndMessage;
3810			return ERROR;
3811		}
3812
3813		glBindVertexArray(0);
3814		glBindVertexBuffer(0, m_vbo, 0, 12);
3815		if (glGetError() != GL_INVALID_OPERATION)
3816		{
3817			m_context.getTestContext().getLog()
3818				<< tcu::TestLog::Message << "INVALID_OPERATION should be generated." << tcu::TestLog::EndMessage;
3819			return ERROR;
3820		}
3821
3822		return NO_ERROR;
3823	}
3824};
3825
3826//=============================================================================
3827// 4.2 NegativeVertexAttribFormat
3828//-----------------------------------------------------------------------------
3829class NegativeVertexAttribFormat : public VertexAttribBindingBase
3830{
3831	GLuint m_vao, m_vbo;
3832
3833	virtual long Setup()
3834	{
3835		glGenVertexArrays(1, &m_vao);
3836		glGenBuffers(1, &m_vbo);
3837		return NO_ERROR;
3838	}
3839
3840	virtual long Cleanup()
3841	{
3842		glDeleteVertexArrays(1, &m_vao);
3843		glDeleteBuffers(1, &m_vbo);
3844		return NO_ERROR;
3845	}
3846
3847	virtual long Run()
3848	{
3849		GLenum glError;
3850
3851		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
3852		glBufferData(GL_ARRAY_BUFFER, 1000, NULL, GL_STATIC_DRAW);
3853		glBindBuffer(GL_ARRAY_BUFFER, 0);
3854
3855		glBindVertexArray(m_vao);
3856
3857		GLint p;
3858		glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &p);
3859		glVertexAttribFormat(p + 1, 4, GL_FLOAT, GL_FALSE, 0);
3860		if (glGetError() != GL_INVALID_VALUE)
3861		{
3862			m_context.getTestContext().getLog()
3863				<< tcu::TestLog::Message << "INVALID_VALUE should be generated." << tcu::TestLog::EndMessage;
3864			return ERROR;
3865		}
3866		glVertexAttribIFormat(p + 2, 4, GL_INT, 0);
3867		if (glGetError() != GL_INVALID_VALUE)
3868		{
3869			m_context.getTestContext().getLog()
3870				<< tcu::TestLog::Message << "INVALID_VALUE should be generated." << tcu::TestLog::EndMessage;
3871			return ERROR;
3872		}
3873		glVertexAttribLFormat(p + 3, 4, GL_DOUBLE, 0);
3874		if (glGetError() != GL_INVALID_VALUE)
3875		{
3876			m_context.getTestContext().getLog()
3877				<< tcu::TestLog::Message << "INVALID_VALUE should be generated." << tcu::TestLog::EndMessage;
3878			return ERROR;
3879		}
3880
3881		glVertexAttribFormat(0, 0, GL_FLOAT, GL_FALSE, 0);
3882		if (glGetError() != GL_INVALID_VALUE)
3883		{
3884			m_context.getTestContext().getLog()
3885				<< tcu::TestLog::Message << "INVALID_VALUE should be generated." << tcu::TestLog::EndMessage;
3886			return ERROR;
3887		}
3888		glVertexAttribFormat(0, 5, GL_FLOAT, GL_FALSE, 0);
3889		if (glGetError() != GL_INVALID_VALUE)
3890		{
3891			m_context.getTestContext().getLog()
3892				<< tcu::TestLog::Message << "INVALID_VALUE should be generated." << tcu::TestLog::EndMessage;
3893			return ERROR;
3894		}
3895		glVertexAttribIFormat(0, 5, GL_INT, 0);
3896		if (glGetError() != GL_INVALID_VALUE)
3897		{
3898			m_context.getTestContext().getLog()
3899				<< tcu::TestLog::Message << "INVALID_VALUE should be generated." << tcu::TestLog::EndMessage;
3900			return ERROR;
3901		}
3902		glVertexAttribLFormat(0, 0, GL_DOUBLE, 0);
3903		if (glGetError() != GL_INVALID_VALUE)
3904		{
3905			m_context.getTestContext().getLog()
3906				<< tcu::TestLog::Message << "INVALID_VALUE should be generated." << tcu::TestLog::EndMessage;
3907			return ERROR;
3908		}
3909		glVertexAttribIFormat(0, GL_BGRA, GL_INT, 0);
3910		glError = glGetError();
3911		if (glError != GL_INVALID_OPERATION && glError != GL_INVALID_VALUE)
3912		{
3913			//two possible errors here: INVALID_VALUE because GL_BGRA used in *IFormat
3914			//function AND INVALID_OPERATION because GL_BGRA used with GL_INT
3915			m_context.getTestContext().getLog()
3916				<< tcu::TestLog::Message << "INVALID_OPERATION should be generated." << tcu::TestLog::EndMessage;
3917			return ERROR;
3918		}
3919		glVertexAttribLFormat(0, GL_BGRA, GL_DOUBLE, 0);
3920		glError = glGetError();
3921		if (glError != GL_INVALID_OPERATION && glError != GL_INVALID_VALUE)
3922		{
3923			//two possible errors here: INVALID_VALUE because GL_BGRA used in *IFormat
3924			//function AND INVALID_OPERATION because GL_BGRA used with GL_DOUBLE
3925			m_context.getTestContext().getLog()
3926				<< tcu::TestLog::Message << "INVALID_VALUE should be generated." << tcu::TestLog::EndMessage;
3927			return ERROR;
3928		}
3929		glVertexAttribFormat(0, 4, GL_R32F, GL_FALSE, 0);
3930		if (glGetError() != GL_INVALID_ENUM)
3931		{
3932			m_context.getTestContext().getLog()
3933				<< tcu::TestLog::Message << "INVALID_ENUM should be generated." << tcu::TestLog::EndMessage;
3934			return ERROR;
3935		}
3936		glVertexAttribIFormat(0, 4, GL_FLOAT, 0);
3937		if (glGetError() != GL_INVALID_ENUM)
3938		{
3939			m_context.getTestContext().getLog()
3940				<< tcu::TestLog::Message << "INVALID_ENUM should be generated." << tcu::TestLog::EndMessage;
3941			return ERROR;
3942		}
3943		glVertexAttribLFormat(0, 4, GL_INT, 0);
3944		if (glGetError() != GL_INVALID_ENUM)
3945		{
3946			m_context.getTestContext().getLog()
3947				<< tcu::TestLog::Message << "INVALID_ENUM should be generated." << tcu::TestLog::EndMessage;
3948			return ERROR;
3949		}
3950		glVertexAttribFormat(0, GL_BGRA, GL_FLOAT, GL_TRUE, 0);
3951		if (glGetError() != GL_INVALID_OPERATION)
3952		{
3953			m_context.getTestContext().getLog()
3954				<< tcu::TestLog::Message << "INVALID_OPERATION should be generated." << tcu::TestLog::EndMessage;
3955			return ERROR;
3956		}
3957		glVertexAttribFormat(0, 3, GL_INT_2_10_10_10_REV, GL_FALSE, 0);
3958		if (glGetError() != GL_INVALID_OPERATION)
3959		{
3960			m_context.getTestContext().getLog()
3961				<< tcu::TestLog::Message << "INVALID_OPERATION should be generated." << tcu::TestLog::EndMessage;
3962			return ERROR;
3963		}
3964		glVertexAttribFormat(0, GL_BGRA, GL_UNSIGNED_BYTE, GL_FALSE, 0);
3965		if (glGetError() != GL_INVALID_OPERATION)
3966		{
3967			m_context.getTestContext().getLog()
3968				<< tcu::TestLog::Message << "INVALID_OPERATION should be generated." << tcu::TestLog::EndMessage;
3969			return ERROR;
3970		}
3971		glGetIntegerv(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
3972		glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, p + 10);
3973		if (glGetError() != GL_INVALID_VALUE)
3974		{
3975			m_context.getTestContext().getLog()
3976				<< tcu::TestLog::Message << "INVALID_VALUE should be generated." << tcu::TestLog::EndMessage;
3977			return ERROR;
3978		}
3979		glVertexAttribIFormat(0, 4, GL_INT, p + 10);
3980		if (glGetError() != GL_INVALID_VALUE)
3981		{
3982			m_context.getTestContext().getLog()
3983				<< tcu::TestLog::Message << "INVALID_VALUE should be generated." << tcu::TestLog::EndMessage;
3984			return ERROR;
3985		}
3986		glVertexAttribLFormat(0, 4, GL_DOUBLE, p + 10);
3987		if (glGetError() != GL_INVALID_VALUE)
3988		{
3989			m_context.getTestContext().getLog()
3990				<< tcu::TestLog::Message << "INVALID_VALUE should be generated." << tcu::TestLog::EndMessage;
3991			return ERROR;
3992		}
3993		glBindVertexArray(0);
3994		glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, 0);
3995		if (glGetError() != GL_INVALID_OPERATION)
3996		{
3997			m_context.getTestContext().getLog()
3998				<< tcu::TestLog::Message << "INVALID_OPERATION should be generated." << tcu::TestLog::EndMessage;
3999			return ERROR;
4000		}
4001		glVertexAttribIFormat(0, 4, GL_INT, 0);
4002		if (glGetError() != GL_INVALID_OPERATION)
4003		{
4004			m_context.getTestContext().getLog()
4005				<< tcu::TestLog::Message << "INVALID_OPERATION should be generated." << tcu::TestLog::EndMessage;
4006			return ERROR;
4007		}
4008		glVertexAttribLFormat(0, 4, GL_DOUBLE, 0);
4009		if (glGetError() != GL_INVALID_OPERATION)
4010		{
4011			m_context.getTestContext().getLog()
4012				<< tcu::TestLog::Message << "INVALID_OPERATION should be generated." << tcu::TestLog::EndMessage;
4013			return ERROR;
4014		}
4015		return NO_ERROR;
4016	}
4017};
4018
4019//=============================================================================
4020// 4.3 NegativeVertexAttribBinding
4021//-----------------------------------------------------------------------------
4022class NegativeVertexAttribBinding : public VertexAttribBindingBase
4023{
4024	GLuint m_vao;
4025
4026	virtual long Setup()
4027	{
4028		glGenVertexArrays(1, &m_vao);
4029		return NO_ERROR;
4030	}
4031
4032	virtual long Cleanup()
4033	{
4034		glDeleteVertexArrays(1, &m_vao);
4035		return NO_ERROR;
4036	}
4037
4038	virtual long Run()
4039	{
4040		glBindVertexArray(m_vao);
4041		GLint p;
4042		glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &p);
4043		glVertexAttribBinding(p + 1, 0);
4044		if (glGetError() != GL_INVALID_VALUE)
4045		{
4046			m_context.getTestContext().getLog()
4047				<< tcu::TestLog::Message << "INVALID_VALUE should be generated." << tcu::TestLog::EndMessage;
4048			return ERROR;
4049		}
4050		glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &p);
4051		glVertexAttribBinding(0, p + 1);
4052		if (glGetError() != GL_INVALID_VALUE)
4053		{
4054			m_context.getTestContext().getLog()
4055				<< tcu::TestLog::Message << "INVALID_VALUE should be generated." << tcu::TestLog::EndMessage;
4056			return ERROR;
4057		}
4058		glBindVertexArray(0);
4059		glVertexAttribBinding(0, 0);
4060		if (glGetError() != GL_INVALID_OPERATION)
4061		{
4062			m_context.getTestContext().getLog()
4063				<< tcu::TestLog::Message << "INVALID_OPERATION should be generated." << tcu::TestLog::EndMessage;
4064			return ERROR;
4065		}
4066		return NO_ERROR;
4067	}
4068};
4069//=============================================================================
4070// 4.4 NegativeVertexAttribDivisor
4071//-----------------------------------------------------------------------------
4072class NegativeVertexAttribDivisor : public VertexAttribBindingBase
4073{
4074	GLuint m_vao;
4075
4076	virtual long Setup()
4077	{
4078		glGenVertexArrays(1, &m_vao);
4079		return NO_ERROR;
4080	}
4081
4082	virtual long Cleanup()
4083	{
4084		glDeleteVertexArrays(1, &m_vao);
4085		return NO_ERROR;
4086	}
4087
4088	virtual long Run()
4089	{
4090		glBindVertexArray(m_vao);
4091		GLint p;
4092		glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &p);
4093		glVertexBindingDivisor(p + 1, 1);
4094		if (glGetError() != GL_INVALID_VALUE)
4095		{
4096			m_context.getTestContext().getLog()
4097				<< tcu::TestLog::Message << "INVALID_VALUE should be generated." << tcu::TestLog::EndMessage;
4098			return ERROR;
4099		}
4100		glBindVertexArray(0);
4101		glVertexBindingDivisor(0, 1);
4102		if (glGetError() != GL_INVALID_OPERATION)
4103		{
4104			m_context.getTestContext().getLog()
4105				<< tcu::TestLog::Message << "INVALID_OPERATION should be generated." << tcu::TestLog::EndMessage;
4106			return ERROR;
4107		}
4108		return NO_ERROR;
4109	}
4110};
4111
4112} // anonymous namespace
4113
4114VertexAttribBindingTests::VertexAttribBindingTests(deqp::Context& context)
4115	: TestCaseGroup(context, "vertex_attrib_binding", "")
4116{
4117}
4118
4119VertexAttribBindingTests::~VertexAttribBindingTests(void)
4120{
4121}
4122
4123void VertexAttribBindingTests::init()
4124{
4125	using namespace deqp;
4126	addChild(new TestSubcase(m_context, "basic-usage", TestSubcase::Create<BasicUsage>));
4127	addChild(new TestSubcase(m_context, "basic-input-case1", TestSubcase::Create<BasicInputCase1>));
4128	addChild(new TestSubcase(m_context, "basic-input-case2", TestSubcase::Create<BasicInputCase2>));
4129	addChild(new TestSubcase(m_context, "basic-input-case3", TestSubcase::Create<BasicInputCase3>));
4130	addChild(new TestSubcase(m_context, "basic-input-case4", TestSubcase::Create<BasicInputCase4>));
4131	addChild(new TestSubcase(m_context, "basic-input-case5", TestSubcase::Create<BasicInputCase5>));
4132	addChild(new TestSubcase(m_context, "basic-input-case6", TestSubcase::Create<BasicInputCase6>));
4133	addChild(new TestSubcase(m_context, "basic-input-case7", TestSubcase::Create<BasicInputCase7>));
4134	addChild(new TestSubcase(m_context, "basic-input-case8", TestSubcase::Create<BasicInputCase8>));
4135	addChild(new TestSubcase(m_context, "basic-input-case9", TestSubcase::Create<BasicInputCase9>));
4136	addChild(new TestSubcase(m_context, "basic-input-case10", TestSubcase::Create<BasicInputCase10>));
4137	addChild(new TestSubcase(m_context, "basic-input-case11", TestSubcase::Create<BasicInputCase11>));
4138	addChild(new TestSubcase(m_context, "basic-input-case12", TestSubcase::Create<BasicInputCase12>));
4139	addChild(new TestSubcase(m_context, "basic-inputI-case1", TestSubcase::Create<BasicInputICase1>));
4140	addChild(new TestSubcase(m_context, "basic-inputI-case2", TestSubcase::Create<BasicInputICase2>));
4141	addChild(new TestSubcase(m_context, "basic-inputI-case3", TestSubcase::Create<BasicInputICase3>));
4142	addChild(new TestSubcase(m_context, "basic-inputL-case1", TestSubcase::Create<BasicInputLCase1>));
4143	addChild(new TestSubcase(m_context, "basic-inputL-case2", TestSubcase::Create<BasicInputLCase2>));
4144	addChild(new TestSubcase(m_context, "basic-state1", TestSubcase::Create<BasicState1>));
4145	addChild(new TestSubcase(m_context, "basic-state2", TestSubcase::Create<BasicState2>));
4146	addChild(new TestSubcase(m_context, "basic-state3", TestSubcase::Create<BasicState3>));
4147	addChild(new TestSubcase(m_context, "basic-state4", TestSubcase::Create<BasicState4>));
4148	addChild(new TestSubcase(m_context, "advanced-bindingUpdate", TestSubcase::Create<AdvancedBindingUpdate>));
4149	addChild(new TestSubcase(m_context, "advanced-instancing", TestSubcase::Create<AdvancedInstancing>));
4150	addChild(new TestSubcase(m_context, "advanced-iterations", TestSubcase::Create<AdvancedIterations>));
4151	addChild(new TestSubcase(m_context, "advanced-largeStrideAndOffsetsNewAndLegacyAPI",
4152							 TestSubcase::Create<AdvancedLargeStrideAndOffsetsNewAndLegacyAPI>));
4153	addChild(new TestSubcase(m_context, "negative-bindVertexBuffer", TestSubcase::Create<NegativeBindVertexBuffer>));
4154	addChild(
4155		new TestSubcase(m_context, "negative-vertexAttribFormat", TestSubcase::Create<NegativeVertexAttribFormat>));
4156	addChild(
4157		new TestSubcase(m_context, "negative-vertexAttribBinding", TestSubcase::Create<NegativeVertexAttribBinding>));
4158	addChild(
4159		new TestSubcase(m_context, "negative-vertexAttribDivisor", TestSubcase::Create<NegativeVertexAttribDivisor>));
4160}
4161
4162} // namespace gl4cts
4163