• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
32 namespace gl4cts
33 {
34 
35 using namespace glw;
36 using tcu::Vec4;
37 using tcu::IVec4;
38 using tcu::UVec4;
39 using tcu::DVec4;
40 using tcu::Vec3;
41 using tcu::IVec3;
42 using tcu::DVec3;
43 using tcu::Vec2;
44 using tcu::IVec2;
45 using tcu::UVec2;
46 using tcu::Mat4;
47 
48 namespace
49 {
50 
51 class VertexAttribBindingBase : public deqp::SubcaseBase
52 {
53 
Title()54 	virtual std::string Title()
55 	{
56 		return NL "";
57 	}
58 
Purpose()59 	virtual std::string Purpose()
60 	{
61 		return NL "";
62 	}
63 
Method()64 	virtual std::string Method()
65 	{
66 		return NL "";
67 	}
68 
PassCriteria()69 	virtual std::string PassCriteria()
70 	{
71 		return NL "";
72 	}
73 
74 public:
getWindowWidth()75 	int getWindowWidth()
76 	{
77 		const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
78 		return renderTarget.getWidth();
79 	}
80 
getWindowHeight()81 	int getWindowHeight()
82 	{
83 		const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
84 		return renderTarget.getHeight();
85 	}
86 
ColorEqual(const Vec4 & c0,const Vec4 & c1,const Vec4 & epsilon)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 
ColorEqual(const Vec3 & c0,const Vec3 & c1,const Vec4 & epsilon)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 
CheckRectColor(const std::vector<Vec3> & fb,int fb_w,int rx,int ry,int rw,int rh,const Vec3 & expected)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 
CheckRectColor(const std::vector<Vec4> & fb,int fb_w,int rx,int ry,int rw,int rh,const Vec4 & expected)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 
CheckProgram(GLuint program)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 
IsEqual(IVec4 a,IVec4 b)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 
IsEqual(UVec4 a,UVec4 b)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 
IsEqual(Vec2 a,Vec2 b)259 	bool IsEqual(Vec2 a, Vec2 b)
260 	{
261 		return (a[0] == b[0]) && (a[1] == b[1]);
262 	}
263 
IsEqual(IVec2 a,IVec2 b)264 	bool IsEqual(IVec2 a, IVec2 b)
265 	{
266 		return (a[0] == b[0]) && (a[1] == b[1]);
267 	}
268 
IsEqual(UVec2 a,UVec2 b)269 	bool IsEqual(UVec2 a, UVec2 b)
270 	{
271 		return (a[0] == b[0]) && (a[1] == b[1]);
272 	}
273 
Translation(float tx,float ty,float tz)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 //-----------------------------------------------------------------------------
284 class BasicUsage : public VertexAttribBindingBase
285 {
286 	GLuint m_vsp, m_fsp, m_ppo, m_vao, m_vbo;
287 
Setup()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 
Cleanup()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 
Run()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 //-----------------------------------------------------------------------------
372 class BasicInputBase : public VertexAttribBindingBase
373 {
374 	GLuint m_po, m_xfbo;
375 
376 protected:
377 	Vec4	expected_data[64];
378 	GLsizei instance_count;
379 	GLint   base_instance;
380 
Setup()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 
Cleanup()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 
Run()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 //-----------------------------------------------------------------------------
471 class BasicInputCase1 : public BasicInputBase
472 {
473 	GLuint m_vao, m_vbo;
474 
Setup()475 	virtual long Setup()
476 	{
477 		BasicInputBase::Setup();
478 		glGenVertexArrays(1, &m_vao);
479 		glGenBuffers(1, &m_vbo);
480 		return NO_ERROR;
481 	}
482 
Cleanup()483 	virtual long Cleanup()
484 	{
485 		BasicInputBase::Cleanup();
486 		glDeleteVertexArrays(1, &m_vao);
487 		glDeleteBuffers(1, &m_vbo);
488 		return NO_ERROR;
489 	}
490 
Run()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 //-----------------------------------------------------------------------------
518 class BasicInputCase2 : public BasicInputBase
519 {
520 	GLuint m_vao, m_vbo;
521 
Setup()522 	virtual long Setup()
523 	{
524 		BasicInputBase::Setup();
525 		glGenVertexArrays(1, &m_vao);
526 		glGenBuffers(1, &m_vbo);
527 		return NO_ERROR;
528 	}
529 
Cleanup()530 	virtual long Cleanup()
531 	{
532 		BasicInputBase::Cleanup();
533 		glDeleteVertexArrays(1, &m_vao);
534 		glDeleteBuffers(1, &m_vbo);
535 		return NO_ERROR;
536 	}
537 
Run()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 //-----------------------------------------------------------------------------
580 class BasicInputCase3 : public BasicInputBase
581 {
582 	GLuint m_vao, m_vbo;
583 
Setup()584 	virtual long Setup()
585 	{
586 		BasicInputBase::Setup();
587 		glGenVertexArrays(1, &m_vao);
588 		glGenBuffers(1, &m_vbo);
589 		return NO_ERROR;
590 	}
591 
Cleanup()592 	virtual long Cleanup()
593 	{
594 		BasicInputBase::Cleanup();
595 		glDeleteVertexArrays(1, &m_vao);
596 		glDeleteBuffers(1, &m_vbo);
597 		return NO_ERROR;
598 	}
599 
Run()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 //-----------------------------------------------------------------------------
647 class BasicInputCase4 : public BasicInputBase
648 {
649 	GLuint m_vao, m_vbo[2];
650 
Setup()651 	virtual long Setup()
652 	{
653 		BasicInputBase::Setup();
654 		glGenVertexArrays(1, &m_vao);
655 		glGenBuffers(2, m_vbo);
656 		return NO_ERROR;
657 	}
658 
Cleanup()659 	virtual long Cleanup()
660 	{
661 		BasicInputBase::Cleanup();
662 		glDeleteVertexArrays(1, &m_vao);
663 		glDeleteBuffers(2, m_vbo);
664 		return NO_ERROR;
665 	}
666 
Run()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 //-----------------------------------------------------------------------------
742 class BasicInputCase5 : public BasicInputBase
743 {
744 	GLuint m_vao, m_vbo;
745 
Setup()746 	virtual long Setup()
747 	{
748 		BasicInputBase::Setup();
749 		glGenVertexArrays(1, &m_vao);
750 		glGenBuffers(1, &m_vbo);
751 		return NO_ERROR;
752 	}
753 
Cleanup()754 	virtual long Cleanup()
755 	{
756 		BasicInputBase::Cleanup();
757 		glDeleteVertexArrays(1, &m_vao);
758 		glDeleteBuffers(1, &m_vbo);
759 		return NO_ERROR;
760 	}
761 
Run()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 //-----------------------------------------------------------------------------
917 class BasicInputCase6 : public BasicInputBase
918 {
919 	GLuint m_vao, m_vbo;
920 
Setup()921 	virtual long Setup()
922 	{
923 		BasicInputBase::Setup();
924 		glGenVertexArrays(1, &m_vao);
925 		glGenBuffers(1, &m_vbo);
926 		return NO_ERROR;
927 	}
928 
Cleanup()929 	virtual long Cleanup()
930 	{
931 		BasicInputBase::Cleanup();
932 		glDeleteVertexArrays(1, &m_vao);
933 		glDeleteBuffers(1, &m_vbo);
934 		return NO_ERROR;
935 	}
936 
Run()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 //-----------------------------------------------------------------------------
1074 class BasicInputCase7 : public BasicInputBase
1075 {
1076 	GLuint m_vao, m_vbo[2];
1077 
Setup()1078 	virtual long Setup()
1079 	{
1080 		BasicInputBase::Setup();
1081 		glGenVertexArrays(1, &m_vao);
1082 		glGenBuffers(2, m_vbo);
1083 		return NO_ERROR;
1084 	}
1085 
Cleanup()1086 	virtual long Cleanup()
1087 	{
1088 		BasicInputBase::Cleanup();
1089 		glDeleteVertexArrays(1, &m_vao);
1090 		glDeleteBuffers(2, m_vbo);
1091 		return NO_ERROR;
1092 	}
1093 
Run()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 //-----------------------------------------------------------------------------
1154 class BasicInputCase8 : public BasicInputBase
1155 {
1156 	GLuint m_vao, m_vbo[2];
1157 
Setup()1158 	virtual long Setup()
1159 	{
1160 		BasicInputBase::Setup();
1161 		glGenVertexArrays(1, &m_vao);
1162 		glGenBuffers(2, m_vbo);
1163 		return NO_ERROR;
1164 	}
1165 
Cleanup()1166 	virtual long Cleanup()
1167 	{
1168 		BasicInputBase::Cleanup();
1169 		glDeleteVertexArrays(1, &m_vao);
1170 		glDeleteBuffers(2, m_vbo);
1171 		return NO_ERROR;
1172 	}
1173 
Run()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 //-----------------------------------------------------------------------------
1233 class BasicInputCase9 : public BasicInputBase
1234 {
1235 	GLuint m_vao, m_vbo[2];
1236 
Setup()1237 	virtual long Setup()
1238 	{
1239 		BasicInputBase::Setup();
1240 		glGenVertexArrays(1, &m_vao);
1241 		glGenBuffers(2, m_vbo);
1242 		return NO_ERROR;
1243 	}
1244 
Cleanup()1245 	virtual long Cleanup()
1246 	{
1247 		BasicInputBase::Cleanup();
1248 		glDeleteVertexArrays(1, &m_vao);
1249 		glDeleteBuffers(2, m_vbo);
1250 		return NO_ERROR;
1251 	}
1252 
Run()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 //-----------------------------------------------------------------------------
1307 class BasicInputCase10 : public BasicInputBase
1308 {
1309 	GLuint m_vao, m_vbo;
1310 
Setup()1311 	virtual long Setup()
1312 	{
1313 		BasicInputBase::Setup();
1314 		glGenVertexArrays(1, &m_vao);
1315 		glGenBuffers(1, &m_vbo);
1316 		return NO_ERROR;
1317 	}
1318 
Cleanup()1319 	virtual long Cleanup()
1320 	{
1321 		BasicInputBase::Cleanup();
1322 		glDeleteVertexArrays(1, &m_vao);
1323 		glDeleteBuffers(1, &m_vbo);
1324 		return NO_ERROR;
1325 	}
1326 
Run()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 //-----------------------------------------------------------------------------
1370 class BasicInputCase11 : public BasicInputBase
1371 {
1372 	GLuint m_vao, m_vbo[2];
1373 
Setup()1374 	virtual long Setup()
1375 	{
1376 		BasicInputBase::Setup();
1377 		glGenVertexArrays(1, &m_vao);
1378 		glGenBuffers(2, m_vbo);
1379 		return NO_ERROR;
1380 	}
1381 
Cleanup()1382 	virtual long Cleanup()
1383 	{
1384 		BasicInputBase::Cleanup();
1385 		glDeleteVertexArrays(1, &m_vao);
1386 		glDeleteBuffers(2, m_vbo);
1387 		return NO_ERROR;
1388 	}
1389 
Run()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 //-----------------------------------------------------------------------------
1443 class BasicInputCase12 : public BasicInputBase
1444 {
1445 	GLuint m_vao, m_vbo;
1446 
Setup()1447 	virtual long Setup()
1448 	{
1449 		BasicInputBase::Setup();
1450 		glGenVertexArrays(1, &m_vao);
1451 		glGenBuffers(1, &m_vbo);
1452 		return NO_ERROR;
1453 	}
1454 
Cleanup()1455 	virtual long Cleanup()
1456 	{
1457 		BasicInputBase::Cleanup();
1458 		glDeleteVertexArrays(1, &m_vao);
1459 		glDeleteBuffers(1, &m_vbo);
1460 		return NO_ERROR;
1461 	}
1462 
Run()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 //-----------------------------------------------------------------------------
1498 class BasicInputIBase : public VertexAttribBindingBase
1499 {
1500 	GLuint m_po, m_xfbo;
1501 
1502 protected:
1503 	IVec4   expected_datai[32];
1504 	UVec4   expected_dataui[32];
1505 	GLsizei instance_count;
1506 	GLuint  base_instance;
1507 
Setup()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 
Cleanup()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 
Run()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 //-----------------------------------------------------------------------------
1612 class BasicInputICase1 : public BasicInputIBase
1613 {
1614 	GLuint m_vao, m_vbo;
1615 
Setup()1616 	virtual long Setup()
1617 	{
1618 		BasicInputIBase::Setup();
1619 		glGenVertexArrays(1, &m_vao);
1620 		glGenBuffers(1, &m_vbo);
1621 		return NO_ERROR;
1622 	}
1623 
Cleanup()1624 	virtual long Cleanup()
1625 	{
1626 		BasicInputIBase::Cleanup();
1627 		glDeleteVertexArrays(1, &m_vao);
1628 		glDeleteBuffers(1, &m_vbo);
1629 		return NO_ERROR;
1630 	}
1631 
Run()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 //-----------------------------------------------------------------------------
1759 class BasicInputICase2 : public BasicInputIBase
1760 {
1761 	GLuint m_vao, m_vbo[2];
1762 
Setup()1763 	virtual long Setup()
1764 	{
1765 		BasicInputIBase::Setup();
1766 		glGenVertexArrays(1, &m_vao);
1767 		glGenBuffers(2, m_vbo);
1768 		return NO_ERROR;
1769 	}
1770 
Cleanup()1771 	virtual long Cleanup()
1772 	{
1773 		BasicInputIBase::Cleanup();
1774 		glDeleteVertexArrays(1, &m_vao);
1775 		glDeleteBuffers(2, m_vbo);
1776 		return NO_ERROR;
1777 	}
1778 
Run()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 //-----------------------------------------------------------------------------
1834 class BasicInputICase3 : public BasicInputIBase
1835 {
1836 	GLuint m_vao, m_vbo;
1837 
Setup()1838 	virtual long Setup()
1839 	{
1840 		BasicInputIBase::Setup();
1841 		glGenVertexArrays(1, &m_vao);
1842 		glGenBuffers(1, &m_vbo);
1843 		return NO_ERROR;
1844 	}
1845 
Cleanup()1846 	virtual long Cleanup()
1847 	{
1848 		BasicInputIBase::Cleanup();
1849 		glDeleteVertexArrays(1, &m_vao);
1850 		glDeleteBuffers(1, &m_vbo);
1851 		return NO_ERROR;
1852 	}
1853 
Run()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 //-----------------------------------------------------------------------------
1890 class BasicInputLBase : public VertexAttribBindingBase
1891 {
1892 	GLuint m_po, m_xfbo;
1893 
1894 protected:
1895 	DVec4   expected_data[32];
1896 	GLsizei instance_count;
1897 	GLuint  base_instance;
1898 
Setup()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 
Cleanup()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 
Run()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 //-----------------------------------------------------------------------------
1986 class BasicInputLCase1 : public BasicInputLBase
1987 {
1988 	GLuint m_vao, m_vbo;
1989 
Setup()1990 	virtual long Setup()
1991 	{
1992 		BasicInputLBase::Setup();
1993 		glGenVertexArrays(1, &m_vao);
1994 		glGenBuffers(1, &m_vbo);
1995 		return NO_ERROR;
1996 	}
1997 
Cleanup()1998 	virtual long Cleanup()
1999 	{
2000 		BasicInputLBase::Cleanup();
2001 		glDeleteVertexArrays(1, &m_vao);
2002 		glDeleteBuffers(1, &m_vbo);
2003 		return NO_ERROR;
2004 	}
2005 
Run()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 //-----------------------------------------------------------------------------
2051 class BasicInputLCase2 : public BasicInputLBase
2052 {
2053 	GLuint m_vao, m_vbo[2];
2054 
Setup()2055 	virtual long Setup()
2056 	{
2057 		BasicInputLBase::Setup();
2058 		glGenVertexArrays(1, &m_vao);
2059 		glGenBuffers(2, m_vbo);
2060 		return NO_ERROR;
2061 	}
2062 
Cleanup()2063 	virtual long Cleanup()
2064 	{
2065 		BasicInputLBase::Cleanup();
2066 		glDeleteVertexArrays(1, &m_vao);
2067 		glDeleteBuffers(2, m_vbo);
2068 		return NO_ERROR;
2069 	}
2070 
Run()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 //-----------------------------------------------------------------------------
2124 class BasicState1 : public VertexAttribBindingBase
2125 {
2126 	GLuint m_vao, m_vbo[2];
2127 
Setup()2128 	virtual long Setup()
2129 	{
2130 		glGenVertexArrays(1, &m_vao);
2131 		glGenBuffers(2, m_vbo);
2132 		return NO_ERROR;
2133 	}
2134 
Cleanup()2135 	virtual long Cleanup()
2136 	{
2137 		glDeleteVertexArrays(1, &m_vao);
2138 		glDeleteBuffers(2, m_vbo);
2139 		return NO_ERROR;
2140 	}
2141 
Run()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 //-----------------------------------------------------------------------------
2381 class BasicState2 : public VertexAttribBindingBase
2382 {
2383 	GLuint m_vao, m_vbo;
2384 
Setup()2385 	virtual long Setup()
2386 	{
2387 		glGenVertexArrays(1, &m_vao);
2388 		glGenBuffers(1, &m_vbo);
2389 		return NO_ERROR;
2390 	}
2391 
Cleanup()2392 	virtual long Cleanup()
2393 	{
2394 		glDeleteVertexArrays(1, &m_vao);
2395 		glDeleteBuffers(1, &m_vbo);
2396 		return NO_ERROR;
2397 	}
2398 
Run()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 
2434 class VertexAttribState : public deqp::GLWrapper
2435 {
2436 public:
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 
VertexAttribState(int attribindex)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 
stateVerify()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 
2572 class VertexBindingState : public deqp::GLWrapper
2573 {
2574 public:
2575 	int		 buffer;
2576 	long int offset;
2577 	int		 stride;
2578 	int		 divisor;
2579 	int		 index;
2580 
VertexBindingState(int bindingindex)2581 	VertexBindingState(int bindingindex) : buffer(0), offset(0), stride(16), divisor(0), index(bindingindex)
2582 	{
2583 	}
2584 
stateVerify()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 //-----------------------------------------------------------------------------
2626 class BasicState3 : public VertexAttribBindingBase
2627 {
2628 
2629 	GLuint m_vao, m_vbo[3];
2630 
Setup()2631 	virtual long Setup()
2632 	{
2633 		glGenVertexArrays(1, &m_vao);
2634 		glGenBuffers(3, m_vbo);
2635 		return NO_ERROR;
2636 	}
2637 
Cleanup()2638 	virtual long Cleanup()
2639 	{
2640 		glDeleteVertexArrays(1, &m_vao);
2641 		glDeleteBuffers(3, m_vbo);
2642 		return NO_ERROR;
2643 	}
2644 
Run()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 //-----------------------------------------------------------------------------
2861 class BasicState4 : public VertexAttribBindingBase
2862 {
2863 	GLuint m_vao;
2864 
Setup()2865 	virtual long Setup()
2866 	{
2867 		glGenVertexArrays(1, &m_vao);
2868 		return NO_ERROR;
2869 	}
2870 
Cleanup()2871 	virtual long Cleanup()
2872 	{
2873 		glDeleteVertexArrays(1, &m_vao);
2874 		return NO_ERROR;
2875 	}
2876 
Run()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 //-----------------------------------------------------------------------------
2953 class AdvancedBindingUpdate : public VertexAttribBindingBase
2954 {
2955 	GLuint m_vao[2], m_vbo[2], m_ebo[2], m_vsp, m_fsp, m_ppo;
2956 
Setup()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 
Cleanup()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 
Run()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 //-----------------------------------------------------------------------------
3203 class 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 
Setup()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 
Cleanup()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 
Run()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 //-----------------------------------------------------------------------------
3423 class AdvancedIterations : public VertexAttribBindingBase
3424 {
3425 	GLuint m_po, m_vao[2], m_xfo[2], m_buffer[2];
3426 
Setup()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 
Cleanup()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 
Run()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 
RelinkProgram(GLuint index)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 //-----------------------------------------------------------------------------
3601 class AdvancedLargeStrideAndOffsetsNewAndLegacyAPI : public VertexAttribBindingBase
3602 {
3603 	GLuint m_vsp, m_ppo, m_ssbo, m_vao, m_vbo;
3604 
Setup()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 
Cleanup()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 
Run()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 //-----------------------------------------------------------------------------
3754 class NegativeBindVertexBuffer : public VertexAttribBindingBase
3755 {
3756 	GLuint m_vao, m_vbo;
3757 
Setup()3758 	virtual long Setup()
3759 	{
3760 		glGenVertexArrays(1, &m_vao);
3761 		glGenBuffers(1, &m_vbo);
3762 		return NO_ERROR;
3763 	}
3764 
Cleanup()3765 	virtual long Cleanup()
3766 	{
3767 		glDeleteVertexArrays(1, &m_vao);
3768 		glDeleteBuffers(1, &m_vbo);
3769 		return NO_ERROR;
3770 	}
3771 
Run()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 //-----------------------------------------------------------------------------
3829 class NegativeVertexAttribFormat : public VertexAttribBindingBase
3830 {
3831 	GLuint m_vao, m_vbo;
3832 
Setup()3833 	virtual long Setup()
3834 	{
3835 		glGenVertexArrays(1, &m_vao);
3836 		glGenBuffers(1, &m_vbo);
3837 		return NO_ERROR;
3838 	}
3839 
Cleanup()3840 	virtual long Cleanup()
3841 	{
3842 		glDeleteVertexArrays(1, &m_vao);
3843 		glDeleteBuffers(1, &m_vbo);
3844 		return NO_ERROR;
3845 	}
3846 
Run()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 //-----------------------------------------------------------------------------
4022 class NegativeVertexAttribBinding : public VertexAttribBindingBase
4023 {
4024 	GLuint m_vao;
4025 
Setup()4026 	virtual long Setup()
4027 	{
4028 		glGenVertexArrays(1, &m_vao);
4029 		return NO_ERROR;
4030 	}
4031 
Cleanup()4032 	virtual long Cleanup()
4033 	{
4034 		glDeleteVertexArrays(1, &m_vao);
4035 		return NO_ERROR;
4036 	}
4037 
Run()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 //-----------------------------------------------------------------------------
4072 class NegativeVertexAttribDivisor : public VertexAttribBindingBase
4073 {
4074 	GLuint m_vao;
4075 
Setup()4076 	virtual long Setup()
4077 	{
4078 		glGenVertexArrays(1, &m_vao);
4079 		return NO_ERROR;
4080 	}
4081 
Cleanup()4082 	virtual long Cleanup()
4083 	{
4084 		glDeleteVertexArrays(1, &m_vao);
4085 		return NO_ERROR;
4086 	}
4087 
Run()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 
VertexAttribBindingTests(deqp::Context & context)4114 VertexAttribBindingTests::VertexAttribBindingTests(deqp::Context& context)
4115 	: TestCaseGroup(context, "vertex_attrib_binding", "")
4116 {
4117 }
4118 
~VertexAttribBindingTests(void)4119 VertexAttribBindingTests::~VertexAttribBindingTests(void)
4120 {
4121 }
4122 
init()4123 void 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