• 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 "es31cVertexAttribBindingTests.hpp"
25 #include "glwEnums.hpp"
26 #include "tcuMatrix.hpp"
27 #include "tcuRenderTarget.hpp"
28 #include <cstdarg>
29 
30 #include <cmath>
31 
32 namespace glcts
33 {
34 using namespace glw;
35 using tcu::Vec4;
36 using tcu::IVec4;
37 using tcu::UVec4;
38 using tcu::Vec3;
39 using tcu::IVec3;
40 using tcu::UVec3;
41 using tcu::Vec2;
42 using tcu::IVec2;
43 using tcu::UVec2;
44 using tcu::Mat4;
45 
46 namespace
47 {
48 
49 class VertexAttribBindingBase : public glcts::SubcaseBase
50 {
Title()51 	virtual std::string Title()
52 	{
53 		return NL "";
54 	}
55 
Purpose()56 	virtual std::string Purpose()
57 	{
58 		return NL "";
59 	}
60 
Method()61 	virtual std::string Method()
62 	{
63 		return NL "";
64 	}
65 
PassCriteria()66 	virtual std::string PassCriteria()
67 	{
68 		return NL "";
69 	}
70 
71 public:
IsSSBOInVSFSAvailable(int required)72 	bool IsSSBOInVSFSAvailable(int required)
73 	{
74 		GLint blocksVS, blocksFS;
75 		glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &blocksVS);
76 		glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &blocksFS);
77 		if (blocksVS >= required && blocksFS >= required)
78 			return true;
79 		else
80 		{
81 			std::ostringstream reason;
82 			reason << "Required " << required << " VS storage blocks but only " << blocksVS << " available."
83 				   << std::endl
84 				   << "Required " << required << " FS storage blocks but only " << blocksFS << " available."
85 				   << std::endl;
86 			OutputNotSupported(reason.str());
87 			return false;
88 		}
89 	}
90 
getWindowWidth()91 	int getWindowWidth()
92 	{
93 		const tcu::RenderTarget& renderTarget = m_context.getRenderTarget();
94 		return renderTarget.getWidth();
95 	}
96 
getWindowHeight()97 	int getWindowHeight()
98 	{
99 		const tcu::RenderTarget& renderTarget = m_context.getRenderTarget();
100 		return renderTarget.getHeight();
101 	}
102 
ColorEqual(const Vec4 & c0,const Vec4 & c1,const Vec4 & epsilon)103 	inline bool ColorEqual(const Vec4& c0, const Vec4& c1, const Vec4& epsilon)
104 	{
105 		if (fabs(c0[0] - c1[0]) > epsilon[0])
106 			return false;
107 		if (fabs(c0[1] - c1[1]) > epsilon[1])
108 			return false;
109 		if (fabs(c0[2] - c1[2]) > epsilon[2])
110 			return false;
111 		if (fabs(c0[3] - c1[3]) > epsilon[3])
112 			return false;
113 		return true;
114 	}
115 
CheckProgram(GLuint program)116 	bool CheckProgram(GLuint program)
117 	{
118 		GLint status;
119 		glGetProgramiv(program, GL_LINK_STATUS, &status);
120 
121 		if (status == GL_FALSE)
122 		{
123 			GLint attached_shaders;
124 			glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders);
125 
126 			if (attached_shaders > 0)
127 			{
128 				std::vector<GLuint> shaders(attached_shaders);
129 				glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]);
130 
131 				for (GLint i = 0; i < attached_shaders; ++i)
132 				{
133 					GLenum type;
134 					glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type));
135 					switch (type)
136 					{
137 					case GL_VERTEX_SHADER:
138 						m_context.getTestContext().getLog()
139 							<< tcu::TestLog::Message << "*** Vertex Shader ***" << tcu::TestLog::EndMessage;
140 						break;
141 					case GL_FRAGMENT_SHADER:
142 						m_context.getTestContext().getLog()
143 							<< tcu::TestLog::Message << "*** Fragment Shader ***" << tcu::TestLog::EndMessage;
144 						break;
145 					default:
146 						m_context.getTestContext().getLog()
147 							<< tcu::TestLog::Message << "*** Unknown Shader ***" << tcu::TestLog::EndMessage;
148 						break;
149 					}
150 					GLint length;
151 					glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length);
152 					if (length > 0)
153 					{
154 						std::vector<GLchar> source(length);
155 						glGetShaderSource(shaders[i], length, NULL, &source[0]);
156 						m_context.getTestContext().getLog()
157 							<< tcu::TestLog::Message << &source[0] << tcu::TestLog::EndMessage;
158 					}
159 					glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length);
160 					if (length > 0)
161 					{
162 						std::vector<GLchar> log(length);
163 						glGetShaderInfoLog(shaders[i], length, NULL, &log[0]);
164 						m_context.getTestContext().getLog()
165 							<< tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
166 					}
167 				}
168 			}
169 			GLint length;
170 			glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
171 			if (length > 0)
172 			{
173 				std::vector<GLchar> log(length);
174 				glGetProgramInfoLog(program, length, NULL, &log[0]);
175 				m_context.getTestContext().getLog() << tcu::TestLog::Message << &log[0] << tcu::TestLog::EndMessage;
176 			}
177 		}
178 		return status == GL_TRUE ? true : false;
179 	}
180 
IsEqual(IVec4 a,IVec4 b)181 	bool IsEqual(IVec4 a, IVec4 b)
182 	{
183 		return (a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]);
184 	}
185 
IsEqual(UVec4 a,UVec4 b)186 	bool IsEqual(UVec4 a, UVec4 b)
187 	{
188 		return (a[0] == b[0]) && (a[1] == b[1]) && (a[2] == b[2]) && (a[3] == b[3]);
189 	}
190 
IsEqual(Vec2 a,Vec2 b)191 	bool IsEqual(Vec2 a, Vec2 b)
192 	{
193 		return (a[0] == b[0]) && (a[1] == b[1]);
194 	}
195 
IsEqual(IVec2 a,IVec2 b)196 	bool IsEqual(IVec2 a, IVec2 b)
197 	{
198 		return (a[0] == b[0]) && (a[1] == b[1]);
199 	}
200 
IsEqual(UVec2 a,UVec2 b)201 	bool IsEqual(UVec2 a, UVec2 b)
202 	{
203 		return (a[0] == b[0]) && (a[1] == b[1]);
204 	}
205 
CheckFB(Vec3 expected)206 	bool CheckFB(Vec3 expected)
207 	{
208 		const tcu::RenderTarget& renderTarget = m_context.getRenderContext().getRenderTarget();
209 		const tcu::PixelFormat&  pixelFormat  = renderTarget.getPixelFormat();
210 		Vec3					 g_color_eps  = Vec3(1.f / static_cast<float>(1 << pixelFormat.redBits),
211 								1.f / static_cast<float>(1 << pixelFormat.greenBits),
212 								1.f / static_cast<float>(1 << pixelFormat.blueBits));
213 		Vec3				 g_color_max = Vec3(255);
214 		std::vector<GLubyte> fb(getWindowWidth() * getWindowHeight() * 4);
215 		int					 fb_w = getWindowWidth();
216 		int					 fb_h = getWindowHeight();
217 		glReadPixels(0, 0, fb_w, fb_h, GL_RGBA, GL_UNSIGNED_BYTE, &fb[0]);
218 		for (GLint i = 0, y = 0; y < fb_h; ++y)
219 			for (GLint x = 0; x < fb_w; ++x, i += 4)
220 			{
221 				if (fabs(fb[i + 0] / g_color_max[0] - expected[0]) > g_color_eps[0] ||
222 					fabs(fb[i + 1] / g_color_max[1] - expected[1]) > g_color_eps[1] ||
223 					fabs(fb[i + 2] / g_color_max[2] - expected[2]) > g_color_eps[2])
224 				{
225 					m_context.getTestContext().getLog()
226 						<< tcu::TestLog::Message << "Incorrect framebuffer color at pixel (" << x << " " << y
227 						<< "). Color is (" << fb[i + 0] / g_color_max[0] << " " << fb[i + 1] / g_color_max[1] << " "
228 						<< fb[i + 2] / g_color_max[2] << ". Color should be (" << expected[0] << " " << expected[1]
229 						<< " " << expected[2] << ")." << tcu::TestLog::EndMessage;
230 					return false;
231 				}
232 			}
233 		return true;
234 	}
235 
FloatToHalf(float f)236 	GLhalf FloatToHalf(float f)
237 	{
238 		const unsigned int HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP = 0x38000000;
239 		/* max exponent value in single precision that will be converted */
240 		/* to Inf or Nan when stored as a half-float */
241 		const unsigned int HALF_FLOAT_MAX_BIASED_EXP_AS_SINGLE_FP_EXP = 0x47800000;
242 		/* 255 is the max exponent biased value */
243 		const unsigned int FLOAT_MAX_BIASED_EXP		 = (0xFF << 23);
244 		const unsigned int HALF_FLOAT_MAX_BIASED_EXP = (0x1F << 10);
245 		char*			   c						 = reinterpret_cast<char*>(&f);
246 		unsigned int	   x						 = *reinterpret_cast<unsigned int*>(c);
247 		unsigned int	   sign						 = (GLhalf)(x >> 31);
248 		unsigned int	   mantissa;
249 		unsigned int	   exp;
250 		GLhalf			   hf;
251 
252 		/* get mantissa */
253 		mantissa = x & ((1 << 23) - 1);
254 		/* get exponent bits */
255 		exp = x & FLOAT_MAX_BIASED_EXP;
256 		if (exp >= HALF_FLOAT_MAX_BIASED_EXP_AS_SINGLE_FP_EXP)
257 		{
258 			/* check if the original single precision float number is a NaN */
259 			if (mantissa && (exp == FLOAT_MAX_BIASED_EXP))
260 			{
261 				/* we have a single precision NaN */
262 				mantissa = (1 << 23) - 1;
263 			}
264 			else
265 			{
266 				/* 16-bit half-float representation stores number as Inf */
267 				mantissa = 0;
268 			}
269 			hf = (GLhalf)((((GLhalf)sign) << 15) | (GLhalf)(HALF_FLOAT_MAX_BIASED_EXP) | (GLhalf)(mantissa >> 13));
270 		}
271 		/* check if exponent is <= -15 */
272 		else if (exp <= HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP)
273 		{
274 			/* store a denorm half-float value or zero */
275 			exp = ((HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP - exp) >> 23) + 14;
276 			// handle 0.0 specially to avoid a right-shift by too many bits
277 			if (exp >= 32)
278 			{
279 				return 0;
280 			}
281 			mantissa |= (1 << 23);
282 			mantissa >>= exp;
283 			hf = (GLhalf)((((GLhalf)sign) << 15) | (GLhalf)(mantissa));
284 		}
285 		else
286 		{
287 			hf = (GLhalf)((((GLhalf)sign) << 15) | (GLhalf)((exp - HALF_FLOAT_MIN_BIASED_EXP_AS_SINGLE_FP_EXP) >> 13) |
288 						  (GLhalf)(mantissa >> 13));
289 		}
290 
291 		return hf;
292 	}
293 };
294 //=============================================================================
295 // 1.1 BasicUsage
296 //-----------------------------------------------------------------------------
297 class BasicUsage : public VertexAttribBindingBase
298 {
299 	bool pipeline;
300 
301 	GLuint m_vsp, m_fsp, m_ppo, m_vao, m_vbo;
302 
Setup()303 	virtual long Setup()
304 	{
305 		if (pipeline)
306 		{
307 			m_vsp = m_fsp = 0;
308 			glGenProgramPipelines(1, &m_ppo);
309 		}
310 		else
311 		{
312 			m_ppo = 0;
313 		}
314 		glGenVertexArrays(1, &m_vao);
315 		glGenBuffers(1, &m_vbo);
316 		return NO_ERROR;
317 	}
318 
Cleanup()319 	virtual long Cleanup()
320 	{
321 		if (pipeline)
322 		{
323 			glDeleteProgram(m_vsp);
324 			glDeleteProgram(m_fsp);
325 			glDeleteProgramPipelines(1, &m_ppo);
326 		}
327 		else
328 		{
329 			glUseProgram(0);
330 			glDeleteProgram(m_ppo);
331 		}
332 		glDeleteVertexArrays(1, &m_vao);
333 		glDeleteBuffers(1, &m_vbo);
334 		return NO_ERROR;
335 	}
336 
Run()337 	virtual long Run()
338 	{
339 		const char* const glsl_vs =
340 			"#version 310 es" NL "layout(location = 7) in vec4 vs_in_position;" NL
341 			"layout(location = 1) in vec3 vs_in_color;" NL "out vec3 g_color;" NL "void main() {" NL
342 			"  gl_Position = vs_in_position;" NL "  g_color = vs_in_color;" NL "}";
343 		const char* const glsl_fs =
344 			"#version 310 es" NL "precision highp float;" NL "in vec3 g_color;" NL "out vec4 fs_out_color;" NL
345 			"void main() {" NL "  fs_out_color = vec4(g_color, 1);" NL "}";
346 		if (pipeline)
347 		{
348 			m_vsp = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);
349 			m_fsp = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &glsl_fs);
350 			if (!CheckProgram(m_vsp) || !CheckProgram(m_fsp))
351 				return ERROR;
352 			glUseProgramStages(m_ppo, GL_VERTEX_SHADER_BIT, m_vsp);
353 			glUseProgramStages(m_ppo, GL_FRAGMENT_SHADER_BIT, m_fsp);
354 		}
355 		else
356 		{
357 			m_ppo			 = glCreateProgram();
358 			const GLuint sh  = glCreateShader(GL_VERTEX_SHADER);
359 			const GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);
360 			glShaderSource(sh, 1, &glsl_vs, NULL);
361 			glShaderSource(fsh, 1, &glsl_fs, NULL);
362 			glCompileShader(sh);
363 			glCompileShader(fsh);
364 			glAttachShader(m_ppo, sh);
365 			glAttachShader(m_ppo, fsh);
366 			glDeleteShader(sh);
367 			glDeleteShader(fsh);
368 			glLinkProgram(m_ppo);
369 			if (!CheckProgram(m_ppo))
370 				return ERROR;
371 		}
372 		/* vbo */
373 		{
374 			const float data[] = {
375 				-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,
376 				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,
377 				1.0f,  0.0f,  -1.0f, 1.0f, 1.0f, 1.0f, 0.0f,  1.0f,  1.0f, 1.0f, 1.0f,  0.0f,
378 			};
379 			glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
380 			glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
381 			glBindBuffer(GL_ARRAY_BUFFER, 0);
382 		}
383 		glBindVertexArray(m_vao);
384 		glVertexAttribFormat(7, 2, GL_FLOAT, GL_FALSE, 0);
385 		glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 8);
386 		glVertexAttribBinding(7, 0);
387 		glVertexAttribBinding(1, 0);
388 		glBindVertexBuffer(0, m_vbo, 0, 20);
389 		glEnableVertexAttribArray(7);
390 		glEnableVertexAttribArray(1);
391 		glBindVertexArray(0);
392 
393 		glClear(GL_COLOR_BUFFER_BIT);
394 		glBindVertexArray(m_vao);
395 		if (pipeline)
396 			glBindProgramPipeline(m_ppo);
397 		else
398 			glUseProgram(m_ppo);
399 
400 		glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
401 		if (!CheckFB(Vec3(0, 1, 0)))
402 			return ERROR;
403 
404 		glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
405 		if (!CheckFB(Vec3(1, 1, 0)))
406 			return ERROR;
407 
408 		return NO_ERROR;
409 	}
410 
411 public:
BasicUsage()412 	BasicUsage() : pipeline(true)
413 	{
414 	}
415 };
416 //=============================================================================
417 // BasicInputBase
418 //-----------------------------------------------------------------------------
419 class BasicInputBase : public VertexAttribBindingBase
420 {
421 
422 	GLuint m_po, m_xfbo;
423 
424 protected:
425 	Vec4	expected_data[60];
426 	GLsizei instance_count;
427 	GLint   base_instance;
428 
Setup()429 	virtual long Setup()
430 	{
431 		m_po = 0;
432 		glGenBuffers(1, &m_xfbo);
433 		for (int i			 = 0; i < 60; ++i)
434 			expected_data[i] = Vec4(0.0f);
435 		instance_count		 = 1;
436 		base_instance		 = -1;
437 		return NO_ERROR;
438 	}
439 
Cleanup()440 	virtual long Cleanup()
441 	{
442 		glDisable(GL_RASTERIZER_DISCARD);
443 		glUseProgram(0);
444 		glDeleteProgram(m_po);
445 		glDeleteBuffers(1, &m_xfbo);
446 		return NO_ERROR;
447 	}
448 
Run()449 	virtual long Run()
450 	{
451 		const char* const glsl_vs =
452 			"#version 310 es" NL "layout(location = 0) in vec4 vs_in_attrib0;" NL
453 			"layout(location = 1) in vec4 vs_in_attrib1;" NL "layout(location = 2) in vec4 vs_in_attrib2;" NL
454 			"layout(location = 3) in vec4 vs_in_attrib3;" NL "layout(location = 4) in vec4 vs_in_attrib4;" NL
455 			"layout(location = 5) in vec4 vs_in_attrib5;" NL "layout(location = 6) in vec4 vs_in_attrib6;" NL
456 			"layout(location = 7) in vec4 vs_in_attrib7;" NL "layout(location = 8) in vec4 vs_in_attrib8;" NL
457 			"layout(location = 9) in vec4 vs_in_attrib9;" NL "layout(location = 10) in vec4 vs_in_attrib10;" NL
458 			"layout(location = 11) in vec4 vs_in_attrib11;" NL "layout(location = 12) in vec4 vs_in_attrib12;" NL
459 			"layout(location = 13) in vec4 vs_in_attrib13;" NL "layout(location = 14) in vec4 vs_in_attrib14;" NL
460 			"out vec4 attrib[15];" NL "void main() {" NL "  attrib[0] = vs_in_attrib0;" NL
461 			"  attrib[1] = vs_in_attrib1;" NL "  attrib[2] = vs_in_attrib2;" NL "  attrib[3] = vs_in_attrib3;" NL
462 			"  attrib[4] = vs_in_attrib4;" NL "  attrib[5] = vs_in_attrib5;" NL "  attrib[6] = vs_in_attrib6;" NL
463 			"  attrib[7] = vs_in_attrib7;" NL "  attrib[8] = vs_in_attrib8;" NL "  attrib[9] = vs_in_attrib9;" NL
464 			"  attrib[10] = vs_in_attrib10;" NL "  attrib[11] = vs_in_attrib11;" NL "  attrib[12] = vs_in_attrib12;" NL
465 			"  attrib[13] = vs_in_attrib13;" NL "  attrib[14] = vs_in_attrib14;" NL "}";
466 		const char* const glsl_fs = "#version 310 es" NL "precision mediump float;" NL "in vec4 attrib[15];" NL
467 									"out vec4 fs_out_color;" NL "void main() {" NL "  fs_out_color = attrib[8];" NL "}";
468 		m_po = glCreateProgram();
469 		/* attach shader */
470 		{
471 			const GLuint sh  = glCreateShader(GL_VERTEX_SHADER);
472 			const GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);
473 			glShaderSource(sh, 1, &glsl_vs, NULL);
474 			glShaderSource(fsh, 1, &glsl_fs, NULL);
475 			glCompileShader(sh);
476 			glCompileShader(fsh);
477 			glAttachShader(m_po, sh);
478 			glAttachShader(m_po, fsh);
479 			glDeleteShader(sh);
480 			glDeleteShader(fsh);
481 		}
482 		/* setup XFB */
483 		{
484 			const GLchar* const v = "attrib";
485 			glTransformFeedbackVaryings(m_po, 1, &v, GL_INTERLEAVED_ATTRIBS);
486 		}
487 		glLinkProgram(m_po);
488 		if (!CheckProgram(m_po))
489 			return ERROR;
490 
491 		/* buffer data */
492 		{
493 			std::vector<GLubyte> zero(sizeof(expected_data));
494 			glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_xfbo);
495 			glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(expected_data), &zero[0], GL_DYNAMIC_DRAW);
496 		}
497 
498 		// capture
499 		glEnable(GL_RASTERIZER_DISCARD);
500 		glUseProgram(m_po);
501 		glBeginTransformFeedback(GL_POINTS);
502 		if (base_instance != -1)
503 		{
504 			glDrawArraysInstancedBaseInstance(GL_POINTS, 0, 2, instance_count, static_cast<GLuint>(base_instance));
505 		}
506 		else
507 		{
508 			glDrawArraysInstanced(GL_POINTS, 0, 2, instance_count);
509 		}
510 		glEndTransformFeedback();
511 
512 		Vec4* data =
513 			static_cast<Vec4*>(glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(Vec4) * 60, GL_MAP_READ_BIT));
514 
515 		long status = NO_ERROR;
516 		for (int i = 0; i < 60; ++i)
517 		{
518 			if (!ColorEqual(expected_data[i], data[i], Vec4(0.01f)))
519 			{
520 				m_context.getTestContext().getLog()
521 					<< tcu::TestLog::Message << "Data is: " << data[i][0] << " " << data[i][1] << " " << data[i][2]
522 					<< " " << data[i][3] << ", data should be: " << expected_data[i][0] << " " << expected_data[i][1]
523 					<< " " << expected_data[i][2] << " " << expected_data[i][3] << ", index is: " << i
524 					<< tcu::TestLog::EndMessage;
525 				status = ERROR;
526 				break;
527 			}
528 		}
529 		return status;
530 	}
531 };
532 
533 //=============================================================================
534 // 1.2.1 BasicInputCase1
535 //-----------------------------------------------------------------------------
536 class BasicInputCase1 : public BasicInputBase
537 {
538 
539 	GLuint m_vao, m_vbo;
540 
Setup()541 	virtual long Setup()
542 	{
543 		BasicInputBase::Setup();
544 		glGenVertexArrays(1, &m_vao);
545 		glGenBuffers(1, &m_vbo);
546 		return NO_ERROR;
547 	}
548 
Cleanup()549 	virtual long Cleanup()
550 	{
551 		BasicInputBase::Cleanup();
552 		glDeleteVertexArrays(1, &m_vao);
553 		glDeleteBuffers(1, &m_vbo);
554 		return NO_ERROR;
555 	}
556 
Run()557 	virtual long Run()
558 	{
559 		for (GLuint i = 0; i < 16; ++i)
560 		{
561 			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
562 		}
563 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
564 		glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 2, NULL, GL_STATIC_DRAW);
565 		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);
566 		glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);
567 		glBindBuffer(GL_ARRAY_BUFFER, 0);
568 
569 		glBindVertexArray(m_vao);
570 		glBindVertexBuffer(0, m_vbo, 0, 12);
571 		glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
572 		glVertexAttribBinding(1, 0);
573 		glEnableVertexAttribArray(1);
574 		expected_data[1]  = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
575 		expected_data[16] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
576 		return BasicInputBase::Run();
577 	}
578 };
579 //=============================================================================
580 // 1.2.2 BasicInputCase2
581 //-----------------------------------------------------------------------------
582 class BasicInputCase2 : public BasicInputBase
583 {
584 
585 	GLuint m_vao, m_vbo;
586 
Setup()587 	virtual long Setup()
588 	{
589 		BasicInputBase::Setup();
590 		glGenVertexArrays(1, &m_vao);
591 		glGenBuffers(1, &m_vbo);
592 		return NO_ERROR;
593 	}
594 
Cleanup()595 	virtual long Cleanup()
596 	{
597 		BasicInputBase::Cleanup();
598 		glDeleteVertexArrays(1, &m_vao);
599 		glDeleteBuffers(1, &m_vbo);
600 		return NO_ERROR;
601 	}
602 
Run()603 	virtual long Run()
604 	{
605 		for (GLuint i = 0; i < 16; ++i)
606 		{
607 			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
608 		}
609 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
610 		glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 2, NULL, GL_STATIC_DRAW);
611 		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);
612 		glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);
613 		glBindBuffer(GL_ARRAY_BUFFER, 0);
614 
615 		glBindVertexArray(m_vao);
616 		glVertexAttribBinding(1, 0);
617 		glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
618 		glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
619 		glVertexAttribFormat(7, 1, GL_FLOAT, GL_FALSE, 8);
620 		glVertexAttribFormat(14, 2, GL_FLOAT, GL_FALSE, 4);
621 		glVertexAttribBinding(0, 0);
622 		glVertexAttribBinding(7, 0);
623 		glVertexAttribBinding(14, 0);
624 		glBindVertexBuffer(0, m_vbo, 0, 12);
625 		glEnableVertexAttribArray(0);
626 		glEnableVertexAttribArray(1);
627 		glEnableVertexAttribArray(7);
628 		glEnableVertexAttribArray(14);
629 
630 		expected_data[0]  = Vec4(1.0f, 2.0f, 0.0f, 1.0f);
631 		expected_data[1]  = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
632 		expected_data[7]  = Vec4(3.0f, 0.0f, 0.0f, 1.0f);
633 		expected_data[14] = Vec4(2.0f, 3.0f, 0.0f, 1.0f);
634 		expected_data[15] = Vec4(4.0f, 5.0f, 0.0f, 1.0f);
635 		expected_data[16] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
636 		expected_data[22] = Vec4(6.0f, 0.0f, 0.0f, 1.0f);
637 		expected_data[29] = Vec4(5.0f, 6.0f, 0.0f, 1.0f);
638 		return BasicInputBase::Run();
639 	}
640 };
641 //=============================================================================
642 // 1.2.3 BasicInputCase3
643 //-----------------------------------------------------------------------------
644 class BasicInputCase3 : public BasicInputBase
645 {
646 
647 	GLuint m_vao, m_vbo;
648 
Setup()649 	virtual long Setup()
650 	{
651 		BasicInputBase::Setup();
652 		glGenVertexArrays(1, &m_vao);
653 		glGenBuffers(1, &m_vbo);
654 		return NO_ERROR;
655 	}
656 
Cleanup()657 	virtual long Cleanup()
658 	{
659 		BasicInputBase::Cleanup();
660 		glDeleteVertexArrays(1, &m_vao);
661 		glDeleteBuffers(1, &m_vbo);
662 		return NO_ERROR;
663 	}
664 
Run()665 	virtual long Run()
666 	{
667 		for (GLuint i = 0; i < 16; ++i)
668 		{
669 			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
670 		}
671 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
672 		glBufferData(GL_ARRAY_BUFFER, 36 * 2, NULL, GL_STATIC_DRAW);
673 		/* */
674 		{
675 			GLubyte d[] = { 1, 2, 3, 4 };
676 			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
677 		}
678 		glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec3), &Vec3(5.0f, 6.0f, 7.0f)[0]);
679 		glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(Vec2), &Vec2(8.0f, 9.0f)[0]);
680 		/* */
681 		{
682 			GLubyte d[] = { 10, 11, 12, 13 };
683 			glBufferSubData(GL_ARRAY_BUFFER, 0 + 36, sizeof(d), d);
684 		}
685 		glBufferSubData(GL_ARRAY_BUFFER, 16 + 36, sizeof(Vec3), &Vec3(14.0f, 15.0f, 16.0f)[0]);
686 		glBufferSubData(GL_ARRAY_BUFFER, 28 + 36, sizeof(Vec2), &Vec2(17.0f, 18.0f)[0]);
687 		glBindBuffer(GL_ARRAY_BUFFER, 0);
688 
689 		glBindVertexArray(m_vao);
690 		glEnableVertexAttribArray(1);
691 		glVertexAttribFormat(0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0);
692 		glVertexAttribBinding(1, 3);
693 		glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 16);
694 		glVertexAttribBinding(2, 3);
695 		glVertexAttribFormat(2, 2, GL_FLOAT, GL_FALSE, 28);
696 		glVertexAttribBinding(0, 3);
697 		glBindVertexBuffer(3, m_vbo, 0, 36);
698 		glEnableVertexAttribArray(0);
699 		glEnableVertexAttribArray(2);
700 
701 		expected_data[0]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
702 		expected_data[1]	  = Vec4(5.0f, 6.0f, 7.0f, 1.0f);
703 		expected_data[2]	  = Vec4(8.0f, 9.0f, 0.0f, 1.0f);
704 		expected_data[0 + 15] = Vec4(10.0f, 11.0f, 12.0f, 13.0f);
705 		expected_data[1 + 15] = Vec4(14.0f, 15.0f, 16.0f, 1.0f);
706 		expected_data[2 + 15] = Vec4(17.0f, 18.0f, 0.0f, 1.0f);
707 		return BasicInputBase::Run();
708 	}
709 };
710 //=============================================================================
711 // 1.2.4 BasicInputCase4
712 //-----------------------------------------------------------------------------
713 class BasicInputCase4 : public BasicInputBase
714 {
715 
716 	GLuint m_vao, m_vbo[2];
717 
Setup()718 	virtual long Setup()
719 	{
720 		BasicInputBase::Setup();
721 		glGenVertexArrays(1, &m_vao);
722 		glGenBuffers(2, m_vbo);
723 		return NO_ERROR;
724 	}
725 
Cleanup()726 	virtual long Cleanup()
727 	{
728 		BasicInputBase::Cleanup();
729 		glDeleteVertexArrays(1, &m_vao);
730 		glDeleteBuffers(2, m_vbo);
731 		return NO_ERROR;
732 	}
733 
Run()734 	virtual long Run()
735 	{
736 		for (GLuint i = 0; i < 16; ++i)
737 		{
738 			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
739 		}
740 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
741 		glBufferData(GL_ARRAY_BUFFER, 20 * 2, NULL, GL_STATIC_DRAW);
742 		/* */
743 		{
744 			GLbyte d[] = { -127, 127, -127, 127 };
745 			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
746 		}
747 		/* */
748 		{
749 			GLushort d[] = { 1, 2, 3, 4 };
750 			glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);
751 		}
752 		/* */
753 		{
754 			GLuint d[] = { 5, 6 };
755 			glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);
756 		}
757 		/* */
758 		{
759 			GLbyte d[] = { 127, -127, 127, -127 };
760 			glBufferSubData(GL_ARRAY_BUFFER, 0 + 20, sizeof(d), d);
761 		}
762 		/* */
763 		{
764 			GLushort d[] = { 7, 8, 9, 10 };
765 			glBufferSubData(GL_ARRAY_BUFFER, 4 + 20, sizeof(d), d);
766 		}
767 		/* */
768 		{
769 			GLuint d[] = { 11, 12 };
770 			glBufferSubData(GL_ARRAY_BUFFER, 12 + 20, sizeof(d), d);
771 		}
772 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
773 		glBufferData(GL_ARRAY_BUFFER, 24 * 2 + 8, NULL, GL_STATIC_DRAW);
774 		/* */
775 		{
776 			GLhalf d[] = { FloatToHalf(0.0), FloatToHalf(100.0), FloatToHalf(200.0) };
777 			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
778 		}
779 		/* */
780 		{
781 			GLhalf d[] = { FloatToHalf(300.0), FloatToHalf(400.0) };
782 			glBufferSubData(GL_ARRAY_BUFFER, 26, sizeof(d), d);
783 		}
784 		glBindBuffer(GL_ARRAY_BUFFER, 0);
785 
786 		glBindVertexArray(m_vao);
787 		glVertexAttribFormat(0, 4, GL_BYTE, GL_TRUE, 0);
788 		glVertexAttribFormat(1, 4, GL_UNSIGNED_SHORT, GL_FALSE, 4);
789 		glVertexAttribFormat(2, 2, GL_UNSIGNED_INT, GL_FALSE, 12);
790 		glVertexAttribFormat(5, 2, GL_HALF_FLOAT, GL_FALSE, 0);
791 		glVertexAttribBinding(0, 0);
792 		glVertexAttribBinding(1, 0);
793 		glVertexAttribBinding(2, 0);
794 		glVertexAttribBinding(5, 6);
795 		glBindVertexBuffer(0, m_vbo[0], 0, 20);
796 		glBindVertexBuffer(6, m_vbo[1], 2, 24);
797 		glEnableVertexAttribArray(0);
798 		glEnableVertexAttribArray(1);
799 		glEnableVertexAttribArray(2);
800 		glEnableVertexAttribArray(5);
801 
802 		expected_data[0]	  = Vec4(-1.0f, 1.0f, -1.0f, 1.0f);
803 		expected_data[1]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
804 		expected_data[2]	  = Vec4(5.0f, 6.0f, 0.0f, 1.0f);
805 		expected_data[5]	  = Vec4(100.0f, 200.0f, 0.0f, 1.0f);
806 		expected_data[0 + 15] = Vec4(1.0f, -1.0f, 1.0f, -1.0f);
807 		expected_data[1 + 15] = Vec4(7.0f, 8.0f, 9.0f, 10.0f);
808 		expected_data[2 + 15] = Vec4(11.0f, 12.0f, 0.0f, 1.0f);
809 		expected_data[5 + 15] = Vec4(300.0f, 400.0f, 0.0f, 1.0f);
810 		return BasicInputBase::Run();
811 	}
812 };
813 //=============================================================================
814 // 1.2.5 BasicInputCase5
815 //-----------------------------------------------------------------------------
816 class BasicInputCase5 : public BasicInputBase
817 {
818 
819 	GLuint m_vao, m_vbo;
820 
Setup()821 	virtual long Setup()
822 	{
823 		BasicInputBase::Setup();
824 		glGenVertexArrays(1, &m_vao);
825 		glGenBuffers(1, &m_vbo);
826 		return NO_ERROR;
827 	}
828 
Cleanup()829 	virtual long Cleanup()
830 	{
831 		BasicInputBase::Cleanup();
832 		glDeleteVertexArrays(1, &m_vao);
833 		glDeleteBuffers(1, &m_vbo);
834 		return NO_ERROR;
835 	}
836 
Run()837 	virtual long Run()
838 	{
839 		for (GLuint i = 0; i < 16; ++i)
840 		{
841 			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
842 		}
843 		const int kStride = 116;
844 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
845 		glBufferData(GL_ARRAY_BUFFER, kStride * 2, NULL, GL_STATIC_DRAW);
846 		/* */
847 		{
848 			GLubyte d[] = { 0, 0xff, 0xff / 2, 0 };
849 			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
850 		}
851 		/* */
852 		{
853 			GLushort d[] = { 0, 0xffff, 0xffff / 2, 0 };
854 			glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);
855 		}
856 		/* */
857 		{
858 			GLuint d[] = { 0, 0xffffffff, 0xffffffff / 2, 0 };
859 			glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);
860 		}
861 		/* */
862 		{
863 			GLbyte d[] = { 0, -127, 127, 0 };
864 			glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(d), d);
865 		}
866 		/* */
867 		{
868 			GLshort d[] = { 0, -32767, 32767, 0 };
869 			glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);
870 		}
871 		/* */
872 		{
873 			GLint d[] = { 0, -2147483647, 2147483647, 0 };
874 			glBufferSubData(GL_ARRAY_BUFFER, 40, sizeof(d), d);
875 		}
876 		/* */
877 		{
878 			GLfloat d[] = { 0, 1.0f, 2.0f, 0 };
879 			glBufferSubData(GL_ARRAY_BUFFER, 56, sizeof(d), d);
880 		}
881 		/* */
882 		{
883 			GLhalf d[] = { FloatToHalf(0.0), FloatToHalf(10.0), FloatToHalf(20.0), FloatToHalf(0.0) };
884 			glBufferSubData(GL_ARRAY_BUFFER, 72, sizeof(d), d);
885 		}
886 		/* */
887 		{
888 			GLubyte d[] = { 0, 0xff / 4, 0xff / 2, 0xff };
889 			glBufferSubData(GL_ARRAY_BUFFER, 104, sizeof(d), d);
890 		}
891 		/* */
892 		{
893 			GLuint d = 0 | (1023 << 10) | (511 << 20) | (1 << 30);
894 			glBufferSubData(GL_ARRAY_BUFFER, 108, sizeof(d), &d);
895 		}
896 		/* */
897 		{
898 			GLint d = 0 | (511 << 10) | (255 << 20) | (0 << 30);
899 			glBufferSubData(GL_ARRAY_BUFFER, 112, sizeof(d), &d);
900 		}
901 
902 		/* */
903 		{
904 			GLubyte d[] = { 0xff, 0xff, 0xff / 2, 0 };
905 			glBufferSubData(GL_ARRAY_BUFFER, 0 + kStride, sizeof(d), d);
906 		}
907 		/* */
908 		{
909 			GLushort d[] = { 0xffff, 0xffff, 0xffff / 2, 0 };
910 			glBufferSubData(GL_ARRAY_BUFFER, 4 + kStride, sizeof(d), d);
911 		}
912 		/* */
913 		{
914 			GLuint d[] = { 0xffffffff, 0xffffffff, 0xffffffff / 2, 0 };
915 			glBufferSubData(GL_ARRAY_BUFFER, 12 + kStride, sizeof(d), d);
916 		}
917 		/* */
918 		{
919 			GLbyte d[] = { 127, -127, 127, 0 };
920 			glBufferSubData(GL_ARRAY_BUFFER, 28 + kStride, sizeof(d), d);
921 		}
922 		/* */
923 		{
924 			GLshort d[] = { 32767, -32767, 32767, 0 };
925 			glBufferSubData(GL_ARRAY_BUFFER, 32 + kStride, sizeof(d), d);
926 		}
927 		/* */
928 		{
929 			GLint d[] = { 2147483647, -2147483647, 2147483647, 0 };
930 			glBufferSubData(GL_ARRAY_BUFFER, 40 + kStride, sizeof(d), d);
931 		}
932 		/* */
933 		{
934 			GLfloat d[] = { 0, 3.0f, 4.0f, 0 };
935 			glBufferSubData(GL_ARRAY_BUFFER, 56 + kStride, sizeof(d), d);
936 		}
937 		/* */
938 		{
939 			GLhalf d[] = { FloatToHalf(0.0), FloatToHalf(30.0), FloatToHalf(40.0), FloatToHalf(0.0) };
940 			glBufferSubData(GL_ARRAY_BUFFER, 72 + kStride, sizeof(d), d);
941 		}
942 		/* */
943 		{
944 			GLubyte d[] = { 0xff, 0xff / 2, 0xff / 4, 0 };
945 			glBufferSubData(GL_ARRAY_BUFFER, 104 + kStride, sizeof(d), d);
946 		}
947 		/* */
948 		{
949 			GLuint d = 0 | (1023 << 10) | (511 << 20) | (2u << 30);
950 			glBufferSubData(GL_ARRAY_BUFFER, 108 + kStride, sizeof(d), &d);
951 		}
952 		/* */
953 		{
954 			GLint d = (-511 & 0x3ff) | (511 << 10) | (255 << 20) | 3 << 30;
955 			glBufferSubData(GL_ARRAY_BUFFER, 112 + kStride, sizeof(d), &d);
956 		}
957 		glBindBuffer(GL_ARRAY_BUFFER, 0);
958 
959 		glBindVertexArray(m_vao);
960 		glVertexAttribFormat(0, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0);
961 		glVertexAttribFormat(1, 4, GL_UNSIGNED_SHORT, GL_TRUE, 4);
962 		glVertexAttribFormat(2, 4, GL_UNSIGNED_INT, GL_TRUE, 12);
963 		glVertexAttribFormat(3, 4, GL_BYTE, GL_TRUE, 28);
964 		glVertexAttribFormat(4, 4, GL_SHORT, GL_TRUE, 32);
965 		glVertexAttribFormat(5, 4, GL_INT, GL_TRUE, 40);
966 		glVertexAttribFormat(6, 4, GL_FLOAT, GL_TRUE, 56);
967 		glVertexAttribFormat(7, 4, GL_HALF_FLOAT, GL_TRUE, 72);
968 		glVertexAttribFormat(8, 4, GL_UNSIGNED_BYTE, GL_TRUE, 104);
969 		glVertexAttribFormat(9, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 108);
970 		glVertexAttribFormat(10, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 108);
971 		glVertexAttribFormat(11, 4, GL_INT_2_10_10_10_REV, GL_TRUE, 112);
972 		glVertexAttribFormat(12, 4, GL_INT_2_10_10_10_REV, GL_TRUE, 112);
973 		for (GLuint i = 0; i < 13; ++i)
974 		{
975 			glVertexAttribBinding(i, 0);
976 			glEnableVertexAttribArray(i);
977 		}
978 		glBindVertexBuffer(0, m_vbo, 0, kStride);
979 
980 		expected_data[0]	   = Vec4(0.0f, 1.0f, 0.5f, 0.0f);
981 		expected_data[1]	   = Vec4(0.0f, 1.0f, 0.5f, 0.0f);
982 		expected_data[2]	   = Vec4(0.0f, 1.0f, 0.5f, 0.0f);
983 		expected_data[3]	   = Vec4(0.0f, -1.0f, 1.0f, 0.0f);
984 		expected_data[4]	   = Vec4(0.0f, -1.0f, 1.0f, 0.0f);
985 		expected_data[5]	   = Vec4(0.0f, -1.0f, 1.0f, 0.0f);
986 		expected_data[6]	   = Vec4(0.0f, 1.0f, 2.0f, 0.0f);
987 		expected_data[7]	   = Vec4(0.0f, 10.0f, 20.0f, 0.0f);
988 		expected_data[8]	   = Vec4(0.0f, 0.25f, 0.5f, 1.0f);
989 		expected_data[9]	   = Vec4(0.0f, 1.0f, 0.5f, 0.33f);
990 		expected_data[10]	  = Vec4(0.0f, 1.0f, 0.5f, 0.33f);
991 		expected_data[11]	  = Vec4(0.0f, 1.0f, 0.5f, 0.0f);
992 		expected_data[12]	  = Vec4(0.0f, 1.0f, 0.5f, 0.0f);
993 		expected_data[0 + 15]  = Vec4(1.0f, 1.0f, 0.5f, 0.0f);
994 		expected_data[1 + 15]  = Vec4(1.0f, 1.0f, 0.5f, 0.0f);
995 		expected_data[2 + 15]  = Vec4(1.0f, 1.0f, 0.5f, 0.0f);
996 		expected_data[3 + 15]  = Vec4(1.0f, -1.0f, 1.0f, 0.0f);
997 		expected_data[4 + 15]  = Vec4(1.0f, -1.0f, 1.0f, 0.0f);
998 		expected_data[5 + 15]  = Vec4(1.0f, -1.0f, 1.0f, 0.0f);
999 		expected_data[6 + 15]  = Vec4(0.0f, 3.0f, 4.0f, 0.0f);
1000 		expected_data[7 + 15]  = Vec4(0.0f, 30.0f, 40.0f, 0.0f);
1001 		expected_data[8 + 15]  = Vec4(1.0f, 0.5f, 0.25f, 0.0f);
1002 		expected_data[9 + 15]  = Vec4(0.0f, 1.0f, 0.5f, 0.66f);
1003 		expected_data[10 + 15] = Vec4(0.0f, 1.0f, 0.5f, 0.66f);
1004 		expected_data[11 + 15] = Vec4(-1.0f, 1.0f, 0.5f, -1.0f);
1005 		expected_data[12 + 15] = Vec4(-1.0f, 1.0f, 0.5f, -1.0f);
1006 		return BasicInputBase::Run();
1007 	}
1008 };
1009 //=============================================================================
1010 // 1.2.6 BasicInputCase6
1011 //-----------------------------------------------------------------------------
1012 class BasicInputCase6 : public BasicInputBase
1013 {
1014 
1015 	GLuint m_vao, m_vbo;
1016 
Setup()1017 	virtual long Setup()
1018 	{
1019 		BasicInputBase::Setup();
1020 		glGenVertexArrays(1, &m_vao);
1021 		glGenBuffers(1, &m_vbo);
1022 		return NO_ERROR;
1023 	}
1024 
Cleanup()1025 	virtual long Cleanup()
1026 	{
1027 		BasicInputBase::Cleanup();
1028 		glDeleteVertexArrays(1, &m_vao);
1029 		glDeleteBuffers(1, &m_vbo);
1030 		return NO_ERROR;
1031 	}
1032 
Run()1033 	virtual long Run()
1034 	{
1035 		for (GLuint i = 0; i < 16; ++i)
1036 		{
1037 			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
1038 		}
1039 		const int kStride = 112;
1040 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1041 		glBufferData(GL_ARRAY_BUFFER, kStride * 2, NULL, GL_STATIC_DRAW);
1042 		/* */
1043 		{
1044 			GLubyte d[] = { 1, 2, 3, 4 };
1045 			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
1046 		}
1047 		/* */
1048 		{
1049 			GLushort d[] = { 5, 6, 7, 8 };
1050 			glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);
1051 		}
1052 		/* */
1053 		{
1054 			GLuint d[] = { 9, 10, 11, 12 };
1055 			glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);
1056 		}
1057 		/* */
1058 		{
1059 			GLbyte d[] = { -1, 2, -3, 4 };
1060 			glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(d), d);
1061 		}
1062 		/* */
1063 		{
1064 			GLshort d[] = { -5, 6, -7, 8 };
1065 			glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);
1066 		}
1067 		/* */
1068 		{
1069 			GLint d[] = { -9, 10, -11, 12 };
1070 			glBufferSubData(GL_ARRAY_BUFFER, 40, sizeof(d), d);
1071 		}
1072 		/* */
1073 		{
1074 			GLfloat d[] = { -13.0f, 14.0f, -15.0f, 16.0f };
1075 			glBufferSubData(GL_ARRAY_BUFFER, 56, sizeof(d), d);
1076 		}
1077 		/* */
1078 		{
1079 			GLhalf d[] = { FloatToHalf(-18.0), FloatToHalf(19.0), FloatToHalf(-20.0), FloatToHalf(21.0) };
1080 			glBufferSubData(GL_ARRAY_BUFFER, 72, sizeof(d), d);
1081 		}
1082 		/* */
1083 		{
1084 			GLuint d = 0 | (11 << 10) | (12 << 20) | (2u << 30);
1085 			glBufferSubData(GL_ARRAY_BUFFER, 104, sizeof(d), &d);
1086 		}
1087 		/* */
1088 		{
1089 			GLint d = 0 | ((0xFFFFFFF5 << 10) & (0x3ff << 10)) | (12 << 20) | (1 << 30);
1090 			glBufferSubData(GL_ARRAY_BUFFER, 108, sizeof(d), &d);
1091 		}
1092 
1093 		/* */
1094 		{
1095 			GLubyte d[] = { 22, 23, 24, 25 };
1096 			glBufferSubData(GL_ARRAY_BUFFER, 0 + kStride, sizeof(d), d);
1097 		}
1098 		/* */
1099 		{
1100 			GLushort d[] = { 26, 27, 28, 29 };
1101 			glBufferSubData(GL_ARRAY_BUFFER, 4 + kStride, sizeof(d), d);
1102 		}
1103 		/* */
1104 		{
1105 			GLuint d[] = { 30, 31, 32, 33 };
1106 			glBufferSubData(GL_ARRAY_BUFFER, 12 + kStride, sizeof(d), d);
1107 		}
1108 		/* */
1109 		{
1110 			GLbyte d[] = { -34, 35, -36, 37 };
1111 			glBufferSubData(GL_ARRAY_BUFFER, 28 + kStride, sizeof(d), d);
1112 		}
1113 		/* */
1114 		{
1115 			GLshort d[] = { -38, 39, -40, 41 };
1116 			glBufferSubData(GL_ARRAY_BUFFER, 32 + kStride, sizeof(d), d);
1117 		}
1118 		/* */
1119 		{
1120 			GLint d[] = { -42, 43, -44, 45 };
1121 			glBufferSubData(GL_ARRAY_BUFFER, 40 + kStride, sizeof(d), d);
1122 		}
1123 		/* */
1124 		{
1125 			GLfloat d[] = { -46.0f, 47.0f, -48.0f, 49.0f };
1126 			glBufferSubData(GL_ARRAY_BUFFER, 56 + kStride, sizeof(d), d);
1127 		}
1128 		/* */
1129 		{
1130 			GLhalf d[] = { FloatToHalf(-50.0), FloatToHalf(51.0), FloatToHalf(-52.0), FloatToHalf(53.0) };
1131 			glBufferSubData(GL_ARRAY_BUFFER, 72 + kStride, sizeof(d), d);
1132 		}
1133 		/* */
1134 		{
1135 			GLuint d = 0 | (11 << 10) | (12 << 20) | (1 << 30);
1136 			glBufferSubData(GL_ARRAY_BUFFER, 104 + kStride, sizeof(d), &d);
1137 		}
1138 		/* */
1139 		{
1140 			GLint d = 123 | ((0xFFFFFFFD << 10) & (0x3ff << 10)) | ((0xFFFFFE0C << 20) & (0x3ff << 20)) |
1141 					  ((0xFFFFFFFF << 30) & (0x3 << 30));
1142 			glBufferSubData(GL_ARRAY_BUFFER, 108 + kStride, sizeof(d), &d);
1143 		}
1144 		glBindBuffer(GL_ARRAY_BUFFER, 0);
1145 
1146 		glBindVertexArray(m_vao);
1147 		glVertexAttribFormat(0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0);
1148 		glVertexAttribFormat(1, 4, GL_UNSIGNED_SHORT, GL_FALSE, 4);
1149 		glVertexAttribFormat(2, 4, GL_UNSIGNED_INT, GL_FALSE, 12);
1150 		glVertexAttribFormat(3, 4, GL_BYTE, GL_FALSE, 28);
1151 		glVertexAttribFormat(4, 4, GL_SHORT, GL_FALSE, 32);
1152 		glVertexAttribFormat(5, 4, GL_INT, GL_FALSE, 40);
1153 		glVertexAttribFormat(6, 4, GL_FLOAT, GL_FALSE, 56);
1154 		glVertexAttribFormat(7, 4, GL_HALF_FLOAT, GL_FALSE, 72);
1155 		glVertexAttribFormat(8, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 104);
1156 		glVertexAttribFormat(9, 4, GL_INT_2_10_10_10_REV, GL_FALSE, 108);
1157 		for (GLuint i = 0; i < 10; ++i)
1158 		{
1159 			glVertexAttribBinding(i, 0);
1160 			glEnableVertexAttribArray(i);
1161 		}
1162 		glBindVertexBuffer(0, m_vbo, 0, kStride);
1163 
1164 		expected_data[0]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1165 		expected_data[1]	  = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1166 		expected_data[2]	  = Vec4(9.0f, 10.0f, 11.0f, 12.0f);
1167 		expected_data[3]	  = Vec4(-1.0f, 2.0f, -3.0f, 4.0f);
1168 		expected_data[4]	  = Vec4(-5.0f, 6.0f, -7.0f, 8.0f);
1169 		expected_data[5]	  = Vec4(-9.0f, 10.0f, -11.0f, 12.0f);
1170 		expected_data[6]	  = Vec4(-13.0f, 14.0f, -15.0f, 16.0f);
1171 		expected_data[7]	  = Vec4(-18.0f, 19.0f, -20.0f, 21.0f);
1172 		expected_data[8]	  = Vec4(0.0f, 11.0f, 12.0f, 2.0f);
1173 		expected_data[9]	  = Vec4(0.0f, -11.0f, 12.0f, 1.0f);
1174 		expected_data[0 + 15] = Vec4(22.0f, 23.0f, 24.0f, 25.0f);
1175 		expected_data[1 + 15] = Vec4(26.0f, 27.0f, 28.0f, 29.0f);
1176 		expected_data[2 + 15] = Vec4(30.0f, 31.0f, 32.0f, 33.0f);
1177 		expected_data[3 + 15] = Vec4(-34.0f, 35.0f, -36.0f, 37.0f);
1178 		expected_data[4 + 15] = Vec4(-38.0f, 39.0f, -40.0f, 41.0f);
1179 		expected_data[5 + 15] = Vec4(-42.0f, 43.0f, -44.0f, 45.0f);
1180 		expected_data[6 + 15] = Vec4(-46.0f, 47.0f, -48.0f, 49.0f);
1181 		expected_data[7 + 15] = Vec4(-50.0f, 51.0f, -52.0f, 53.0f);
1182 		expected_data[8 + 15] = Vec4(0.0f, 11.0f, 12.0f, 1.0f);
1183 		expected_data[9 + 15] = Vec4(123.0f, -3.0f, -500.0f, -1.0f);
1184 		return BasicInputBase::Run();
1185 	}
1186 };
1187 //=============================================================================
1188 // 1.2.8 BasicInputCase8
1189 //-----------------------------------------------------------------------------
1190 class BasicInputCase8 : public BasicInputBase
1191 {
1192 
1193 	GLuint m_vao, m_vbo[2];
1194 
Setup()1195 	virtual long Setup()
1196 	{
1197 		BasicInputBase::Setup();
1198 		glGenVertexArrays(1, &m_vao);
1199 		glGenBuffers(2, m_vbo);
1200 		return NO_ERROR;
1201 	}
1202 
Cleanup()1203 	virtual long Cleanup()
1204 	{
1205 		BasicInputBase::Cleanup();
1206 		glDeleteVertexArrays(1, &m_vao);
1207 		glDeleteBuffers(2, m_vbo);
1208 		return NO_ERROR;
1209 	}
1210 
Run()1211 	virtual long Run()
1212 	{
1213 		for (GLuint i = 0; i < 16; ++i)
1214 		{
1215 			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
1216 		}
1217 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
1218 		glBufferData(GL_ARRAY_BUFFER, 6 * 4, NULL, GL_STATIC_DRAW);
1219 		/* */
1220 		{
1221 			GLfloat d[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f };
1222 			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
1223 		}
1224 
1225 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
1226 		glBufferData(GL_ARRAY_BUFFER, 10 * 4, NULL, GL_STATIC_DRAW);
1227 		/* */
1228 		{
1229 			GLfloat d[] = { -1.0f, -2.0f, -3.0f, -4.0f, -5.0f, -6.0f, -7.0f, -8.0f, -9.0f, -10.0f };
1230 			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
1231 		}
1232 		glBindBuffer(GL_ARRAY_BUFFER, 0);
1233 
1234 		glBindVertexArray(m_vao);
1235 		glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
1236 		glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
1237 		glVertexAttribFormat(2, 1, GL_FLOAT, GL_FALSE, 4);
1238 		glVertexAttribFormat(5, 4, GL_FLOAT, GL_FALSE, 12);
1239 		glVertexAttribFormat(14, 2, GL_FLOAT, GL_FALSE, 8);
1240 		glVertexAttribBinding(0, 0);
1241 		glVertexAttribBinding(1, 1);
1242 		glVertexAttribBinding(2, 1);
1243 		glVertexAttribBinding(5, 15);
1244 		glVertexAttribBinding(14, 7);
1245 		glBindVertexBuffer(0, m_vbo[0], 0, 12);
1246 		glBindVertexBuffer(1, m_vbo[0], 4, 4);
1247 		glBindVertexBuffer(7, m_vbo[1], 8, 16);
1248 		glBindVertexBuffer(15, m_vbo[1], 12, 0);
1249 		glEnableVertexAttribArray(0);
1250 		glEnableVertexAttribArray(1);
1251 		glEnableVertexAttribArray(2);
1252 		glEnableVertexAttribArray(5);
1253 		glEnableVertexAttribArray(14);
1254 
1255 		expected_data[0]	   = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
1256 		expected_data[1]	   = Vec4(2.0f, 3.0f, 4.0f, 1.0f);
1257 		expected_data[2]	   = Vec4(3.0f, 0.0f, 0.0f, 1.0f);
1258 		expected_data[5]	   = Vec4(-7.0f, -8.0f, -9.0f, -10.0f);
1259 		expected_data[14]	  = Vec4(-5.0f, -6.0f, 0.0f, 1.0f);
1260 		expected_data[0 + 15]  = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
1261 		expected_data[1 + 15]  = Vec4(3.0f, 4.0f, 5.0f, 1.0f);
1262 		expected_data[2 + 15]  = Vec4(4.0f, 0.0f, 0.0f, 1.0f);
1263 		expected_data[5 + 15]  = Vec4(-7.0f, -8.0f, -9.0f, -10.0f);
1264 		expected_data[14 + 15] = Vec4(-9.0f, -10.0f, 0.0f, 1.0f);
1265 		return BasicInputBase::Run();
1266 	}
1267 };
1268 //=============================================================================
1269 // 1.2.9 BasicInputCase9
1270 //-----------------------------------------------------------------------------
1271 class BasicInputCase9 : public BasicInputBase
1272 {
1273 
1274 	GLuint m_vao, m_vbo[2];
1275 
Setup()1276 	virtual long Setup()
1277 	{
1278 		BasicInputBase::Setup();
1279 		glGenVertexArrays(1, &m_vao);
1280 		glGenBuffers(2, m_vbo);
1281 		return NO_ERROR;
1282 	}
1283 
Cleanup()1284 	virtual long Cleanup()
1285 	{
1286 		BasicInputBase::Cleanup();
1287 		glDeleteVertexArrays(1, &m_vao);
1288 		glDeleteBuffers(2, m_vbo);
1289 		return NO_ERROR;
1290 	}
1291 
Run()1292 	virtual long Run()
1293 	{
1294 		for (GLuint i = 0; i < 16; ++i)
1295 		{
1296 			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
1297 		}
1298 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
1299 		glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);
1300 		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(1.0f, 2.0f, 3.0f, 4.0f)[0]);
1301 		glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(5.0f, 6.0f, 7.0f, 8.0f)[0]);
1302 		glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(Vec4), &Vec4(9.0f, 10.0f, 11.0f, 12.0f)[0]);
1303 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
1304 		glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);
1305 		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(10.0f, 20.0f, 30.0f, 40.0f)[0]);
1306 		glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(50.0f, 60.0f, 70.0f, 80.0f)[0]);
1307 		glBindBuffer(GL_ARRAY_BUFFER, 0);
1308 
1309 		glBindVertexArray(m_vao);
1310 		glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, 0);
1311 		glVertexAttribFormat(2, 4, GL_FLOAT, GL_FALSE, 0);
1312 		glVertexAttribFormat(4, 2, GL_FLOAT, GL_FALSE, 4);
1313 		glVertexAttribBinding(0, 0);
1314 		glVertexAttribBinding(2, 1);
1315 		glVertexAttribBinding(4, 3);
1316 		glEnableVertexAttribArray(0);
1317 		glEnableVertexAttribArray(2);
1318 		glEnableVertexAttribArray(4);
1319 		glBindVertexBuffer(0, m_vbo[0], 0, 16);
1320 		glBindVertexBuffer(1, m_vbo[0], 0, 16);
1321 		glBindVertexBuffer(3, m_vbo[1], 4, 8);
1322 		glVertexBindingDivisor(1, 1);
1323 
1324 		instance_count		  = 2;
1325 		expected_data[0]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1326 		expected_data[2]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1327 		expected_data[4]	  = Vec4(30.0f, 40.0f, 0.0f, 1.0f);
1328 		expected_data[0 + 15] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1329 		expected_data[2 + 15] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1330 		expected_data[4 + 15] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);
1331 
1332 		expected_data[0 + 30]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1333 		expected_data[2 + 30]	  = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1334 		expected_data[4 + 30]	  = Vec4(30.0f, 40.0f, 0.0f, 1.0f);
1335 		expected_data[0 + 15 + 30] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1336 		expected_data[2 + 15 + 30] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1337 		expected_data[4 + 15 + 30] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);
1338 		return BasicInputBase::Run();
1339 	}
1340 };
1341 //=============================================================================
1342 // 1.2.11 BasicInputCase11
1343 //-----------------------------------------------------------------------------
1344 class BasicInputCase11 : public BasicInputBase
1345 {
1346 
1347 	GLuint m_vao, m_vbo[2];
1348 
Setup()1349 	virtual long Setup()
1350 	{
1351 		BasicInputBase::Setup();
1352 		glGenVertexArrays(1, &m_vao);
1353 		glGenBuffers(2, m_vbo);
1354 		return NO_ERROR;
1355 	}
1356 
Cleanup()1357 	virtual long Cleanup()
1358 	{
1359 		BasicInputBase::Cleanup();
1360 		glDeleteVertexArrays(1, &m_vao);
1361 		glDeleteBuffers(2, m_vbo);
1362 		return NO_ERROR;
1363 	}
1364 
Run()1365 	virtual long Run()
1366 	{
1367 		for (GLuint i = 0; i < 16; ++i)
1368 		{
1369 			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
1370 		}
1371 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
1372 		glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);
1373 		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(1.0f, 2.0f, 3.0f, 4.0f)[0]);
1374 		glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(5.0f, 6.0f, 7.0f, 8.0f)[0]);
1375 		glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(Vec4), &Vec4(9.0f, 10.0f, 11.0f, 12.0f)[0]);
1376 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
1377 		glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);
1378 		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(10.0f, 20.0f, 30.0f, 40.0f)[0]);
1379 		glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(50.0f, 60.0f, 70.0f, 80.0f)[0]);
1380 		glBindBuffer(GL_ARRAY_BUFFER, 0);
1381 
1382 		glBindVertexArray(m_vao);
1383 		glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, 0);
1384 		glVertexAttribFormat(2, 4, GL_FLOAT, GL_FALSE, 0);
1385 		glVertexAttribFormat(4, 2, GL_FLOAT, GL_FALSE, 4);
1386 		glVertexAttribBinding(0, 0);
1387 		glVertexAttribBinding(2, 1);
1388 		glVertexAttribBinding(4, 2);
1389 		glEnableVertexAttribArray(0);
1390 		glEnableVertexAttribArray(2);
1391 		glEnableVertexAttribArray(4);
1392 		glBindVertexBuffer(0, m_vbo[0], 0, 16);
1393 		glBindVertexBuffer(1, m_vbo[0], 0, 16);
1394 		glBindVertexBuffer(2, m_vbo[1], 4, 8);
1395 		glVertexBindingDivisor(1, 1);
1396 
1397 		instance_count		  = 2;
1398 		expected_data[0]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1399 		expected_data[2]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1400 		expected_data[4]	  = Vec4(30.0f, 40.0f, 0.0f, 1.0f);
1401 		expected_data[0 + 15] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1402 		expected_data[2 + 15] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1403 		expected_data[4 + 15] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);
1404 
1405 		expected_data[0 + 30]	  = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1406 		expected_data[2 + 30]	  = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1407 		expected_data[4 + 30]	  = Vec4(30.0f, 40.0f, 0.0f, 1.0f);
1408 		expected_data[0 + 15 + 30] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1409 		expected_data[2 + 15 + 30] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1410 		expected_data[4 + 15 + 30] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);
1411 		return BasicInputBase::Run();
1412 	}
1413 };
1414 //=============================================================================
1415 // 1.2.12 BasicInputCase12
1416 //-----------------------------------------------------------------------------
1417 class BasicInputCase12 : public BasicInputBase
1418 {
1419 
1420 	GLuint m_vao, m_vbo;
1421 
Setup()1422 	virtual long Setup()
1423 	{
1424 		BasicInputBase::Setup();
1425 		glGenVertexArrays(1, &m_vao);
1426 		glGenBuffers(1, &m_vbo);
1427 		return NO_ERROR;
1428 	}
1429 
Cleanup()1430 	virtual long Cleanup()
1431 	{
1432 		BasicInputBase::Cleanup();
1433 		glDeleteVertexArrays(1, &m_vao);
1434 		glDeleteBuffers(1, &m_vbo);
1435 		return NO_ERROR;
1436 	}
1437 
Run()1438 	virtual long Run()
1439 	{
1440 		for (GLuint i = 0; i < 16; ++i)
1441 		{
1442 			glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
1443 		}
1444 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1445 		glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 2, NULL, GL_STATIC_DRAW);
1446 		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);
1447 		glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);
1448 		glBindBuffer(GL_ARRAY_BUFFER, 0);
1449 
1450 		glBindVertexArray(m_vao);
1451 
1452 		//glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
1453 		//glVertexAttribBinding(1, 1);
1454 		//glBindVertexBuffer(1, m_vbo, 0, 12);
1455 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1456 		glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 12, 0);
1457 		glBindBuffer(GL_ARRAY_BUFFER, 0);
1458 
1459 		glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
1460 		glVertexAttribBinding(0, 1);
1461 
1462 		glEnableVertexAttribArray(0);
1463 		glEnableVertexAttribArray(1);
1464 
1465 		expected_data[0]	  = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
1466 		expected_data[1]	  = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
1467 		expected_data[0 + 15] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
1468 		expected_data[1 + 15] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
1469 		return BasicInputBase::Run();
1470 	}
1471 };
1472 //=============================================================================
1473 // BasicInputIBase
1474 //-----------------------------------------------------------------------------
1475 class BasicInputIBase : public VertexAttribBindingBase
1476 {
1477 
1478 	GLuint m_po, m_xfbo;
1479 
1480 protected:
1481 	IVec4   expected_datai[32];
1482 	UVec4   expected_dataui[32];
1483 	GLsizei instance_count;
1484 	GLuint  base_instance;
1485 
Setup()1486 	virtual long Setup()
1487 	{
1488 		m_po = 0;
1489 		glGenBuffers(1, &m_xfbo);
1490 		for (int i = 0; i < 32; ++i)
1491 		{
1492 			expected_datai[i]  = IVec4(0);
1493 			expected_dataui[i] = UVec4(0);
1494 		}
1495 		instance_count = 1;
1496 		return NO_ERROR;
1497 	}
1498 
Cleanup()1499 	virtual long Cleanup()
1500 	{
1501 		glDisable(GL_RASTERIZER_DISCARD);
1502 		glUseProgram(0);
1503 		glDeleteProgram(m_po);
1504 		glDeleteBuffers(1, &m_xfbo);
1505 		return NO_ERROR;
1506 	}
1507 
Run()1508 	virtual long Run()
1509 	{
1510 		const char* const glsl_vs =
1511 			"#version 310 es" NL "layout(location = 0) in ivec4 vs_in_attribi0;" NL
1512 			"layout(location = 1) in ivec4 vs_in_attribi1;" NL "layout(location = 2) in ivec4 vs_in_attribi2;" NL
1513 			"layout(location = 3) in ivec4 vs_in_attribi3;" NL "layout(location = 4) in ivec4 vs_in_attribi4;" NL
1514 			"layout(location = 5) in ivec4 vs_in_attribi5;" NL "layout(location = 6) in ivec4 vs_in_attribi6;" NL
1515 			"layout(location = 7) in ivec4 vs_in_attribi7;" NL "layout(location = 8) in uvec4 vs_in_attribui8;" NL
1516 			"layout(location = 9) in uvec4 vs_in_attribui9;" NL "layout(location = 10) in uvec4 vs_in_attribui10;" NL
1517 			"layout(location = 11) in uvec4 vs_in_attribui11;" NL "layout(location = 12) in uvec4 vs_in_attribui12;" NL
1518 			"layout(location = 13) in uvec4 vs_in_attribui13;" NL "layout(location = 14) in uvec4 vs_in_attribui14;" NL
1519 			"layout(location = 15) in uvec4 vs_in_attribui15;" NL "flat out ivec4 attribi[8];" NL
1520 			"flat out uvec4 attribui[7];" NL "void main() {" NL "  attribi[0] = vs_in_attribi0;" NL
1521 			"  attribi[1] = vs_in_attribi1;" NL "  attribi[2] = vs_in_attribi2;" NL "  attribi[3] = vs_in_attribi3;" NL
1522 			"  attribi[4] = vs_in_attribi4;" NL "  attribi[5] = vs_in_attribi5;" NL "  attribi[6] = vs_in_attribi6;" NL
1523 			"  attribi[7] = vs_in_attribi7;" NL "  attribui[0] = vs_in_attribui8;" NL
1524 			"  attribui[1] = vs_in_attribui9;" NL "  attribui[2] = vs_in_attribui10;" NL
1525 			"  attribui[3] = vs_in_attribui11;" NL "  attribui[4] = vs_in_attribui12;" NL
1526 			"  attribui[5] = vs_in_attribui13;" NL "  attribui[6] = vs_in_attribui14;" NL "}";
1527 		const char* const glsl_fs = "#version 310 es" NL "precision mediump float;" NL "flat in ivec4 attribi[8];" NL
1528 									"flat in uvec4 attribui[7];" NL "out vec4 fs_out_color;" NL "void main() {" NL
1529 									"  fs_out_color = vec4(attribui[1]);" NL "}";
1530 		m_po = glCreateProgram();
1531 		/* attach shader */
1532 		{
1533 			const GLuint sh  = glCreateShader(GL_VERTEX_SHADER);
1534 			const GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);
1535 			glShaderSource(sh, 1, &glsl_vs, NULL);
1536 			glShaderSource(fsh, 1, &glsl_fs, NULL);
1537 			glCompileShader(sh);
1538 			glCompileShader(fsh);
1539 			glAttachShader(m_po, sh);
1540 			glAttachShader(m_po, fsh);
1541 			glDeleteShader(sh);
1542 			glDeleteShader(fsh);
1543 		}
1544 		/* setup XFB */
1545 		{
1546 			const GLchar* const v[2] = { "attribi", "attribui" };
1547 			glTransformFeedbackVaryings(m_po, 2, v, GL_INTERLEAVED_ATTRIBS);
1548 		}
1549 		glLinkProgram(m_po);
1550 		if (!CheckProgram(m_po))
1551 			return ERROR;
1552 
1553 		/* buffer data */
1554 		{
1555 			std::vector<GLubyte> zero(64 * 16);
1556 			glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_xfbo);
1557 			glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, (GLsizeiptr)zero.size(), &zero[0], GL_DYNAMIC_COPY);
1558 		}
1559 
1560 		glEnable(GL_RASTERIZER_DISCARD);
1561 		glUseProgram(m_po);
1562 		glBeginTransformFeedback(GL_POINTS);
1563 		glDrawArraysInstanced(GL_POINTS, 0, 2, instance_count);
1564 		glEndTransformFeedback();
1565 
1566 		void*  data   = glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(UVec4) * 64, GL_MAP_READ_BIT);
1567 		IVec4* datai  = static_cast<IVec4*>(data);
1568 		UVec4* dataui = (static_cast<UVec4*>(data)) + 8;
1569 
1570 		for (int i = 0; i < 4; ++i)
1571 			for (int j = 0; j < 8; ++j)
1572 			{
1573 				if (!IsEqual(expected_datai[i * 8 + j], datai[i * 15 + j]))
1574 				{
1575 					m_context.getTestContext().getLog()
1576 						<< tcu::TestLog::Message << "Datai is: " << datai[i * 15 + j][0] << " " << datai[i * 15 + j][1]
1577 						<< " " << datai[i * 15 + j][2] << " " << datai[i * 15 + j][3]
1578 						<< ", data should be: " << expected_datai[i * 8 + j][0] << " " << expected_datai[i * 8 + j][1]
1579 						<< " " << expected_datai[i * 8 + j][2] << " " << expected_datai[i * 8 + j][3]
1580 						<< ", index is: " << i * 8 + j << tcu::TestLog::EndMessage;
1581 					return ERROR;
1582 				}
1583 				if (j != 7 && !IsEqual(expected_dataui[i * 8 + j], dataui[i * 15 + j]))
1584 				{
1585 					m_context.getTestContext().getLog()
1586 						<< tcu::TestLog::Message << "Dataui is: " << dataui[i * 15 + j][0] << " "
1587 						<< dataui[i * 15 + j][1] << " " << dataui[i * 15 + j][2] << " " << dataui[i * 15 + j][3]
1588 						<< ", data should be: " << expected_datai[i * 8 + j][0] << " " << expected_datai[i * 8 + j][1]
1589 						<< " " << expected_datai[i * 8 + j][2] << " " << expected_datai[i * 8 + j][3]
1590 						<< ", index is: " << i * 8 + j << tcu::TestLog::EndMessage;
1591 					return ERROR;
1592 				}
1593 			}
1594 		return NO_ERROR;
1595 	}
1596 };
1597 //=============================================================================
1598 // 1.3.1 BasicInputICase1
1599 //-----------------------------------------------------------------------------
1600 class BasicInputICase1 : public BasicInputIBase
1601 {
1602 
1603 	GLuint m_vao, m_vbo;
1604 
Setup()1605 	virtual long Setup()
1606 	{
1607 		BasicInputIBase::Setup();
1608 		glGenVertexArrays(1, &m_vao);
1609 		glGenBuffers(1, &m_vbo);
1610 		return NO_ERROR;
1611 	}
1612 
Cleanup()1613 	virtual long Cleanup()
1614 	{
1615 		BasicInputIBase::Cleanup();
1616 		glDeleteVertexArrays(1, &m_vao);
1617 		glDeleteBuffers(1, &m_vbo);
1618 		return NO_ERROR;
1619 	}
1620 
Run()1621 	virtual long Run()
1622 	{
1623 		for (GLuint i = 0; i < 8; ++i)
1624 		{
1625 			glVertexAttribI4i(i, 0, 0, 0, 0);
1626 			glVertexAttribI4ui(i + 8, 0, 0, 0, 0);
1627 		}
1628 		const int kStride = 88;
1629 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1630 		glBufferData(GL_ARRAY_BUFFER, kStride * 2, NULL, GL_STATIC_DRAW);
1631 		/* */
1632 		{
1633 			GLbyte d[] = { 1, -2, 3, -4 };
1634 			glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
1635 		}
1636 		/* */
1637 		{
1638 			GLshort d[] = { 5, -6, 7, -8 };
1639 			glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);
1640 		}
1641 		/* */
1642 		{
1643 			GLint d[] = { 9, -10, 11, -12 };
1644 			glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);
1645 		}
1646 		/* */
1647 		{
1648 			GLubyte d[] = { 13, 14, 15, 16 };
1649 			glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(d), d);
1650 		}
1651 		/* */
1652 		{
1653 			GLushort d[] = { 17, 18, 19, 20 };
1654 			glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);
1655 		}
1656 		/* */
1657 		{
1658 			GLuint d[] = { 21, 22, 23, 24 };
1659 			glBufferSubData(GL_ARRAY_BUFFER, 40, sizeof(d), d);
1660 		}
1661 		/* */
1662 		{
1663 			GLint d[] = { 90, -91, 92, -93 };
1664 			glBufferSubData(GL_ARRAY_BUFFER, 56, sizeof(d), d);
1665 		}
1666 		/* */
1667 		{
1668 			GLuint d[] = { 94, 95, 96, 97 };
1669 			glBufferSubData(GL_ARRAY_BUFFER, 72, sizeof(d), d);
1670 		}
1671 
1672 		/* */
1673 		{
1674 			GLbyte d[] = { 25, -26, 27, -28 };
1675 			glBufferSubData(GL_ARRAY_BUFFER, 0 + kStride, sizeof(d), d);
1676 		}
1677 		/* */
1678 		{
1679 			GLshort d[] = { 29, -30, 31, -32 };
1680 			glBufferSubData(GL_ARRAY_BUFFER, 4 + kStride, sizeof(d), d);
1681 		}
1682 		/* */
1683 		{
1684 			GLint d[] = { 33, -34, 35, -36 };
1685 			glBufferSubData(GL_ARRAY_BUFFER, 12 + kStride, sizeof(d), d);
1686 		}
1687 		/* */
1688 		{
1689 			GLubyte d[] = { 37, 38, 39, 40 };
1690 			glBufferSubData(GL_ARRAY_BUFFER, 28 + kStride, sizeof(d), d);
1691 		}
1692 		/* */
1693 		{
1694 			GLushort d[] = { 41, 42, 43, 44 };
1695 			glBufferSubData(GL_ARRAY_BUFFER, 32 + kStride, sizeof(d), d);
1696 		}
1697 		/* */
1698 		{
1699 			GLuint d[] = { 45, 46, 47, 48 };
1700 			glBufferSubData(GL_ARRAY_BUFFER, 40 + kStride, sizeof(d), d);
1701 		}
1702 		/* */
1703 		{
1704 			GLint d[] = { 98, -99, 100, -101 };
1705 			glBufferSubData(GL_ARRAY_BUFFER, 56 + kStride, sizeof(d), d);
1706 		}
1707 		/* */
1708 		{
1709 			GLuint d[] = { 102, 103, 104, 105 };
1710 			glBufferSubData(GL_ARRAY_BUFFER, 72 + kStride, sizeof(d), d);
1711 		}
1712 		glBindBuffer(GL_ARRAY_BUFFER, 0);
1713 
1714 		glBindVertexArray(m_vao);
1715 		glVertexAttribIFormat(0, 1, GL_BYTE, 0);
1716 		glVertexAttribIFormat(1, 2, GL_SHORT, 4);
1717 		glVertexAttribIFormat(2, 3, GL_INT, 12);
1718 		glVertexAttribIFormat(3, 4, GL_INT, 56);
1719 		glVertexAttribIFormat(8, 3, GL_UNSIGNED_BYTE, 28);
1720 		glVertexAttribIFormat(9, 2, GL_UNSIGNED_SHORT, 32);
1721 		glVertexAttribIFormat(10, 1, GL_UNSIGNED_INT, 40);
1722 		glVertexAttribIFormat(11, 4, GL_UNSIGNED_INT, 72);
1723 		glVertexAttribBinding(0, 0);
1724 		glVertexAttribBinding(1, 0);
1725 		glVertexAttribBinding(2, 0);
1726 		glVertexAttribBinding(3, 0);
1727 		glVertexAttribBinding(8, 0);
1728 		glVertexAttribBinding(9, 0);
1729 		glVertexAttribBinding(10, 0);
1730 		glVertexAttribBinding(11, 0);
1731 		glBindVertexBuffer(0, m_vbo, 0, kStride);
1732 		glEnableVertexAttribArray(0);
1733 		glEnableVertexAttribArray(1);
1734 		glEnableVertexAttribArray(2);
1735 		glEnableVertexAttribArray(3);
1736 		glEnableVertexAttribArray(8);
1737 		glEnableVertexAttribArray(9);
1738 		glEnableVertexAttribArray(10);
1739 		glEnableVertexAttribArray(11);
1740 
1741 		expected_datai[0]   = IVec4(1, 0, 0, 1);
1742 		expected_datai[1]   = IVec4(5, -6, 0, 1);
1743 		expected_datai[2]   = IVec4(9, -10, 11, 1);
1744 		expected_datai[3]   = IVec4(90, -91, 92, -93);
1745 		expected_dataui[0]  = UVec4(13, 14, 15, 1);
1746 		expected_dataui[1]  = UVec4(17, 18, 0, 1);
1747 		expected_dataui[2]  = UVec4(21, 0, 0, 1);
1748 		expected_dataui[3]  = UVec4(94, 95, 96, 97);
1749 		expected_datai[8]   = IVec4(25, 0, 0, 1);
1750 		expected_datai[9]   = IVec4(29, -30, 0, 1);
1751 		expected_datai[10]  = IVec4(33, -34, 35, 1);
1752 		expected_datai[11]  = IVec4(98, -99, 100, -101);
1753 		expected_dataui[8]  = UVec4(37, 38, 39, 1);
1754 		expected_dataui[9]  = UVec4(41, 42, 0, 1);
1755 		expected_dataui[10] = UVec4(45, 0, 0, 1);
1756 		expected_dataui[11] = UVec4(102, 103, 104, 105);
1757 		return BasicInputIBase::Run();
1758 	}
1759 };
1760 //=============================================================================
1761 // 1.3.2 BasicInputICase2
1762 //-----------------------------------------------------------------------------
1763 class BasicInputICase2 : public BasicInputIBase
1764 {
1765 
1766 	GLuint m_vao, m_vbo[2];
1767 
Setup()1768 	virtual long Setup()
1769 	{
1770 		BasicInputIBase::Setup();
1771 		glGenVertexArrays(1, &m_vao);
1772 		glGenBuffers(2, m_vbo);
1773 		return NO_ERROR;
1774 	}
1775 
Cleanup()1776 	virtual long Cleanup()
1777 	{
1778 		BasicInputIBase::Cleanup();
1779 		glDeleteVertexArrays(1, &m_vao);
1780 		glDeleteBuffers(2, m_vbo);
1781 		return NO_ERROR;
1782 	}
1783 
Run()1784 	virtual long Run()
1785 	{
1786 		for (GLuint i = 0; i < 8; ++i)
1787 		{
1788 			glVertexAttribI4i(i, 0, 0, 0, 0);
1789 			glVertexAttribI4ui(i + 8, 0, 0, 0, 0);
1790 		}
1791 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
1792 		glBufferData(GL_ARRAY_BUFFER, sizeof(IVec3) * 2, NULL, GL_STATIC_DRAW);
1793 		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(IVec3), &IVec3(1, 2, 3)[0]);
1794 		glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(IVec3), &IVec3(4, 5, 6)[0]);
1795 
1796 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
1797 		glBufferData(GL_ARRAY_BUFFER, sizeof(UVec4), NULL, GL_STATIC_DRAW);
1798 		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(UVec4), &UVec4(10, 20, 30, 40)[0]);
1799 		glBindBuffer(GL_ARRAY_BUFFER, 0);
1800 
1801 		glBindVertexArray(m_vao);
1802 		glVertexAttribIFormat(0, 3, GL_INT, 0);
1803 		glVertexAttribIFormat(2, 2, GL_INT, 4);
1804 		glVertexAttribIFormat(14, 1, GL_UNSIGNED_INT, 0);
1805 		glVertexAttribBinding(0, 2);
1806 		glVertexAttribBinding(2, 0);
1807 		glVertexAttribBinding(14, 7);
1808 		glEnableVertexAttribArray(0);
1809 		glEnableVertexAttribArray(2);
1810 		glEnableVertexAttribArray(14);
1811 		glBindVertexBuffer(0, m_vbo[0], 0, 8);
1812 		glBindVertexBuffer(2, m_vbo[0], 0, 12);
1813 		glBindVertexBuffer(7, m_vbo[1], 4, 16);
1814 		glVertexBindingDivisor(0, 1);
1815 		glVertexBindingDivisor(2, 0);
1816 		glVertexBindingDivisor(7, 2);
1817 
1818 		instance_count		= 2;
1819 		expected_datai[0]   = IVec4(1, 2, 3, 1);
1820 		expected_datai[2]   = IVec4(2, 3, 0, 1);
1821 		expected_dataui[6]  = UVec4(20, 0, 0, 1);
1822 		expected_datai[8]   = IVec4(4, 5, 6, 1);
1823 		expected_datai[10]  = IVec4(2, 3, 0, 1);
1824 		expected_dataui[14] = UVec4(20, 0, 0, 1);
1825 
1826 		expected_datai[16]  = IVec4(1, 2, 3, 1);
1827 		expected_datai[18]  = IVec4(4, 5, 0, 1);
1828 		expected_dataui[22] = UVec4(20, 0, 0, 1);
1829 		expected_datai[24]  = IVec4(4, 5, 6, 1);
1830 		expected_datai[26]  = IVec4(4, 5, 0, 1);
1831 		expected_dataui[30] = UVec4(20, 0, 0, 1);
1832 		return BasicInputIBase::Run();
1833 	}
1834 };
1835 //=============================================================================
1836 // 1.3.3 BasicInputICase3
1837 //-----------------------------------------------------------------------------
1838 class BasicInputICase3 : public BasicInputIBase
1839 {
1840 
1841 	GLuint m_vao, m_vbo;
1842 
Setup()1843 	virtual long Setup()
1844 	{
1845 		BasicInputIBase::Setup();
1846 		glGenVertexArrays(1, &m_vao);
1847 		glGenBuffers(1, &m_vbo);
1848 		return NO_ERROR;
1849 	}
1850 
Cleanup()1851 	virtual long Cleanup()
1852 	{
1853 		BasicInputIBase::Cleanup();
1854 		glDeleteVertexArrays(1, &m_vao);
1855 		glDeleteBuffers(1, &m_vbo);
1856 		return NO_ERROR;
1857 	}
1858 
Run()1859 	virtual long Run()
1860 	{
1861 		for (GLuint i = 0; i < 8; ++i)
1862 		{
1863 			glVertexAttribI4i(i, 0, 0, 0, 0);
1864 			glVertexAttribI4ui(i + 8, 0, 0, 0, 0);
1865 		}
1866 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1867 		glBufferData(GL_ARRAY_BUFFER, sizeof(IVec3) * 2, NULL, GL_STATIC_DRAW);
1868 		glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(IVec3), &IVec3(1, 2, 3)[0]);
1869 		glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(IVec3), &IVec3(4, 5, 6)[0]);
1870 		glBindBuffer(GL_ARRAY_BUFFER, 0);
1871 
1872 		glBindVertexArray(m_vao);
1873 
1874 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1875 		glVertexAttribIPointer(7, 3, GL_INT, 12, 0);
1876 		glBindBuffer(GL_ARRAY_BUFFER, 0);
1877 
1878 		glVertexAttribIFormat(0, 2, GL_INT, 4);
1879 		glVertexAttribBinding(0, 7);
1880 
1881 		glEnableVertexAttribArray(0);
1882 		glEnableVertexAttribArray(7);
1883 
1884 		expected_datai[0]	 = IVec4(2, 3, 0, 1);
1885 		expected_datai[7]	 = IVec4(1, 2, 3, 1);
1886 		expected_datai[0 + 8] = IVec4(5, 6, 0, 1);
1887 		expected_datai[7 + 8] = IVec4(4, 5, 6, 1);
1888 		return BasicInputIBase::Run();
1889 	}
1890 };
1891 
1892 class VertexAttribState : public glcts::GLWrapper
1893 {
1894 public:
1895 	int		  array_enabled;
1896 	int		  array_size;
1897 	int		  array_stride;
1898 	int		  array_type;
1899 	int		  array_normalized;
1900 	int		  array_integer;
1901 	int		  array_divisor;
1902 	deUintptr array_pointer;
1903 	int		  array_buffer_binding;
1904 	int		  binding;
1905 	int		  relative_offset;
1906 	int		  index;
1907 
VertexAttribState(int attribindex)1908 	VertexAttribState(int attribindex)
1909 		: array_enabled(0)
1910 		, array_size(4)
1911 		, array_stride(0)
1912 		, array_type(GL_FLOAT)
1913 		, array_normalized(0)
1914 		, array_integer(0)
1915 		, array_divisor(0)
1916 		, array_pointer(0)
1917 		, array_buffer_binding(0)
1918 		, binding(attribindex)
1919 		, relative_offset(0)
1920 		, index(attribindex)
1921 	{
1922 	}
1923 
stateVerify()1924 	bool stateVerify()
1925 	{
1926 		GLint p;
1927 		bool  status = true;
1928 		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &p);
1929 		if (p != array_enabled)
1930 		{
1931 			m_context.getTestContext().getLog()
1932 				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_ENABLED(" << index << ") is " << p << " should be "
1933 				<< array_enabled << tcu::TestLog::EndMessage;
1934 			status = false;
1935 		}
1936 		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_SIZE, &p);
1937 		if (p != array_size)
1938 		{
1939 			m_context.getTestContext().getLog()
1940 				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_SIZE(" << index << ") is " << p << " should be "
1941 				<< array_size << tcu::TestLog::EndMessage;
1942 			status = false;
1943 		}
1944 		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &p);
1945 		if (p != array_stride)
1946 		{
1947 			m_context.getTestContext().getLog()
1948 				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_STRIDE(" << index << ") is " << p << " should be "
1949 				<< array_stride << tcu::TestLog::EndMessage;
1950 			status = false;
1951 		}
1952 		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_TYPE, &p);
1953 		if (p != array_type)
1954 		{
1955 			m_context.getTestContext().getLog()
1956 				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_TYPE(" << index << ") is " << tcu::toHex(p)
1957 				<< " should be " << tcu::toHex(array_type) << tcu::TestLog::EndMessage;
1958 			status = false;
1959 		}
1960 		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &p);
1961 		if (p != array_normalized)
1962 		{
1963 			m_context.getTestContext().getLog()
1964 				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED(" << index << ") is " << p
1965 				<< " should be " << array_normalized << tcu::TestLog::EndMessage;
1966 			status = false;
1967 		}
1968 		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_INTEGER, &p);
1969 		if (p != array_integer)
1970 		{
1971 			m_context.getTestContext().getLog()
1972 				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_INTEGER(" << index << ") is " << p << " should be "
1973 				<< array_integer << tcu::TestLog::EndMessage;
1974 			status = false;
1975 		}
1976 		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, &p);
1977 		if (p != array_divisor)
1978 		{
1979 			m_context.getTestContext().getLog()
1980 				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_DIVISOR(" << index << ") is " << p << " should be "
1981 				<< array_divisor << tcu::TestLog::EndMessage;
1982 			status = false;
1983 		}
1984 		void* pp;
1985 		glGetVertexAttribPointerv(index, GL_VERTEX_ATTRIB_ARRAY_POINTER, &pp);
1986 		if (reinterpret_cast<deUintptr>(pp) != array_pointer)
1987 		{
1988 			m_context.getTestContext().getLog()
1989 				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_POINTER(" << index << ") is " << pp << " should be "
1990 				<< reinterpret_cast<void*>(array_pointer) << tcu::TestLog::EndMessage;
1991 			status = false;
1992 		}
1993 		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &p);
1994 		if (p != array_buffer_binding)
1995 		{
1996 			m_context.getTestContext().getLog()
1997 				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING(" << index << ") is " << p
1998 				<< " should be " << array_buffer_binding << tcu::TestLog::EndMessage;
1999 			status = false;
2000 		}
2001 		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_BINDING, &p);
2002 		if (static_cast<GLint>(binding) != p)
2003 		{
2004 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_BINDING(" << index
2005 												<< ") is " << p << " should be " << binding << tcu::TestLog::EndMessage;
2006 			status = false;
2007 		}
2008 		glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
2009 		if (p != relative_offset)
2010 		{
2011 			m_context.getTestContext().getLog()
2012 				<< tcu::TestLog::Message << "GL_VERTEX_ATTRIB_RELATIVE_OFFSET(" << index << ") is " << p
2013 				<< " should be " << relative_offset << tcu::TestLog::EndMessage;
2014 			status = false;
2015 		}
2016 		return status;
2017 	}
2018 };
2019 class VertexBindingState : public glcts::GLWrapper
2020 {
2021 public:
2022 	int		 buffer;
2023 	long int offset;
2024 	int		 stride;
2025 	int		 divisor;
2026 	int		 index;
2027 
VertexBindingState(int bindingindex)2028 	VertexBindingState(int bindingindex) : buffer(0), offset(0), stride(16), divisor(0), index(bindingindex)
2029 	{
2030 	}
stateVerify()2031 	bool stateVerify()
2032 	{
2033 		bool  status = true;
2034 		GLint p;
2035 		glGetIntegeri_v(GL_VERTEX_BINDING_BUFFER, index, &p);
2036 		if (p != buffer)
2037 		{
2038 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_BUFFER(" << index
2039 												<< ") is " << p << " should be " << buffer << tcu::TestLog::EndMessage;
2040 			status = false;
2041 		}
2042 		GLint64 p64;
2043 		glGetInteger64i_v(GL_VERTEX_BINDING_OFFSET, index, &p64);
2044 		if (p64 != offset)
2045 		{
2046 			m_context.getTestContext().getLog()
2047 				<< tcu::TestLog::Message << "GL_VERTEX_BINDING_OFFSET(" << index << ") is " << p64 << " should be "
2048 				<< offset << tcu::TestLog::EndMessage;
2049 			status = false;
2050 		}
2051 		glGetIntegeri_v(GL_VERTEX_BINDING_STRIDE, index, &p);
2052 		if (p != stride)
2053 		{
2054 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_STRIDE(" << index
2055 												<< ") is " << p << " should be " << stride << tcu::TestLog::EndMessage;
2056 			status = false;
2057 		}
2058 		glGetIntegeri_v(GL_VERTEX_BINDING_DIVISOR, index, &p);
2059 		if (p != divisor)
2060 		{
2061 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_DIVISOR(" << index
2062 												<< ") is " << p << " should be " << divisor << tcu::TestLog::EndMessage;
2063 			status = false;
2064 		}
2065 		return status;
2066 	}
2067 };
2068 //=============================================================================
2069 // 1.5 BasicState1
2070 //-----------------------------------------------------------------------------
2071 class BasicState1 : public VertexAttribBindingBase
2072 {
2073 
2074 	GLuint m_vao, m_vbo[3];
2075 
Setup()2076 	virtual long Setup()
2077 	{
2078 		glGenVertexArrays(1, &m_vao);
2079 		glGenBuffers(3, m_vbo);
2080 		return NO_ERROR;
2081 	}
2082 
Cleanup()2083 	virtual long Cleanup()
2084 	{
2085 		glDeleteVertexArrays(1, &m_vao);
2086 		glDeleteBuffers(3, m_vbo);
2087 		return NO_ERROR;
2088 	}
2089 
Run()2090 	virtual long Run()
2091 	{
2092 		bool status = true;
2093 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
2094 		glBufferData(GL_ARRAY_BUFFER, 10000, NULL, GL_DYNAMIC_COPY);
2095 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
2096 		glBufferData(GL_ARRAY_BUFFER, 10000, NULL, GL_DYNAMIC_COPY);
2097 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[2]);
2098 		glBufferData(GL_ARRAY_BUFFER, 10000, NULL, GL_DYNAMIC_COPY);
2099 		glBindBuffer(GL_ARRAY_BUFFER, 0);
2100 
2101 		GLint p;
2102 		glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &p);
2103 		if (p < 16)
2104 		{
2105 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_BINDINGS is" << p
2106 												<< "but must be at least 16." << tcu::TestLog::EndMessage;
2107 			status = false;
2108 		}
2109 		glGetIntegerv(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
2110 		if (p < 2047)
2111 		{
2112 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET is"
2113 												<< p << "but must be at least 2047." << tcu::TestLog::EndMessage;
2114 			status = false;
2115 		}
2116 		glGetIntegerv(GL_MAX_VERTEX_ATTRIB_STRIDE, &p);
2117 		if (p < 2048)
2118 		{
2119 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_STRIDE is" << p
2120 												<< "but must be at least 2048." << tcu::TestLog::EndMessage;
2121 			status = false;
2122 		}
2123 
2124 		glBindVertexArray(m_vao);
2125 		// check default state
2126 		glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &p);
2127 		if (0 != p)
2128 		{
2129 			m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_ELEMENT_ARRAY_BUFFER_BINDING is" << p
2130 												<< "should be 0." << tcu::TestLog::EndMessage;
2131 			status = false;
2132 		}
2133 		for (GLuint i = 0; i < 16; ++i)
2134 		{
2135 			VertexAttribState va(i);
2136 			if (!va.stateVerify())
2137 				status = false;
2138 		}
2139 		for (GLuint i = 0; i < 16; ++i)
2140 		{
2141 			VertexBindingState vb(i);
2142 			if (!vb.stateVerify())
2143 				status = false;
2144 		}
2145 		if (!status)
2146 		{
2147 			m_context.getTestContext().getLog()
2148 				<< tcu::TestLog::Message << "Default state check failed." << tcu::TestLog::EndMessage;
2149 			status = false;
2150 		}
2151 
2152 		VertexAttribState va0(0);
2153 		va0.array_size		 = 2;
2154 		va0.array_type		 = GL_BYTE;
2155 		va0.array_normalized = 1;
2156 		va0.relative_offset  = 16;
2157 		VertexBindingState vb0(0);
2158 		glVertexAttribFormat(0, 2, GL_BYTE, GL_TRUE, 16);
2159 		if (!va0.stateVerify() || !vb0.stateVerify())
2160 		{
2161 			m_context.getTestContext().getLog()
2162 				<< tcu::TestLog::Message << "glVertexAttribFormat state change check failed."
2163 				<< tcu::TestLog::EndMessage;
2164 			status = false;
2165 		}
2166 
2167 		VertexAttribState va2(2);
2168 		va2.array_size		= 3;
2169 		va2.array_type		= GL_INT;
2170 		va2.array_integer   = 1;
2171 		va2.relative_offset = 512;
2172 		VertexBindingState vb2(2);
2173 		glVertexAttribIFormat(2, 3, GL_INT, 512);
2174 		if (!va2.stateVerify() || !vb2.stateVerify())
2175 		{
2176 			m_context.getTestContext().getLog()
2177 				<< tcu::TestLog::Message << "glVertexAttribIFormat state change check failed."
2178 				<< tcu::TestLog::EndMessage;
2179 			status = false;
2180 		}
2181 
2182 		va0.array_buffer_binding = m_vbo[0];
2183 		vb0.buffer				 = m_vbo[0];
2184 		vb0.offset				 = 2048;
2185 		vb0.stride				 = 128;
2186 		glBindVertexBuffer(0, m_vbo[0], 2048, 128);
2187 		if (!va0.stateVerify() || !vb0.stateVerify())
2188 		{
2189 			m_context.getTestContext().getLog()
2190 				<< tcu::TestLog::Message << "glBindVertexBuffer state change check failed." << tcu::TestLog::EndMessage;
2191 			status = false;
2192 		}
2193 
2194 		va2.array_buffer_binding = m_vbo[2];
2195 		vb2.buffer				 = m_vbo[2];
2196 		vb2.offset				 = 64;
2197 		vb2.stride				 = 256;
2198 		glBindVertexBuffer(2, m_vbo[2], 64, 256);
2199 		if (!va2.stateVerify() || !vb2.stateVerify())
2200 		{
2201 			m_context.getTestContext().getLog()
2202 				<< tcu::TestLog::Message << "glBindVertexBuffer state change check failed." << tcu::TestLog::EndMessage;
2203 			status = false;
2204 		}
2205 
2206 		glVertexAttribBinding(2, 0);
2207 		va2.binding				 = 0;
2208 		va2.array_buffer_binding = m_vbo[0];
2209 		if (!va0.stateVerify() || !vb0.stateVerify() || !va2.stateVerify() || !vb2.stateVerify())
2210 		{
2211 			m_context.getTestContext().getLog()
2212 				<< tcu::TestLog::Message << "glVertexAttribBinding state change check failed."
2213 				<< tcu::TestLog::EndMessage;
2214 			status = false;
2215 		}
2216 
2217 		VertexAttribState  va15(15);
2218 		VertexBindingState vb15(15);
2219 		glVertexAttribBinding(0, 15);
2220 		va0.binding				 = 15;
2221 		va0.array_buffer_binding = 0;
2222 		if (!va0.stateVerify() || !vb0.stateVerify() || !va15.stateVerify() || !vb15.stateVerify())
2223 		{
2224 			m_context.getTestContext().getLog()
2225 				<< tcu::TestLog::Message << "glVertexAttribBinding state change check failed."
2226 				<< tcu::TestLog::EndMessage;
2227 			status = false;
2228 		}
2229 
2230 		glBindVertexBuffer(15, m_vbo[1], 16, 32);
2231 		va0.array_buffer_binding  = m_vbo[1];
2232 		va15.array_buffer_binding = m_vbo[1];
2233 		vb15.buffer				  = m_vbo[1];
2234 		vb15.offset				  = 16;
2235 		vb15.stride				  = 32;
2236 		if (!va0.stateVerify() || !vb0.stateVerify() || !va15.stateVerify() || !vb15.stateVerify())
2237 		{
2238 			m_context.getTestContext().getLog()
2239 				<< tcu::TestLog::Message << "glBindVertexBuffer state change check failed." << tcu::TestLog::EndMessage;
2240 			status = false;
2241 		}
2242 
2243 		glVertexAttribFormat(15, 1, GL_HALF_FLOAT, GL_FALSE, 1024);
2244 		va15.array_size		 = 1;
2245 		va15.array_type		 = GL_HALF_FLOAT;
2246 		va15.relative_offset = 1024;
2247 		if (!va0.stateVerify() || !vb0.stateVerify() || !va2.stateVerify() || !vb2.stateVerify() ||
2248 			!va15.stateVerify() || !vb15.stateVerify())
2249 		{
2250 			m_context.getTestContext().getLog()
2251 				<< tcu::TestLog::Message << "glVertexAttribFormat state change check failed."
2252 				<< tcu::TestLog::EndMessage;
2253 			status = false;
2254 		}
2255 
2256 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[2]);
2257 		glVertexAttribPointer(0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 8, (void*)640);
2258 		glBindBuffer(GL_ARRAY_BUFFER, 0);
2259 		va0.array_size			 = 4;
2260 		va0.array_type			 = GL_UNSIGNED_BYTE;
2261 		va0.array_stride		 = 8;
2262 		va0.array_pointer		 = 640;
2263 		va0.relative_offset		 = 0;
2264 		va0.array_normalized	 = 0;
2265 		va0.binding				 = 0;
2266 		va0.array_buffer_binding = m_vbo[2];
2267 		vb0.buffer				 = m_vbo[2];
2268 		vb0.offset				 = 640;
2269 		vb0.stride				 = 8;
2270 		va2.array_buffer_binding = m_vbo[2];
2271 		if (!va0.stateVerify() || !vb0.stateVerify() || !va2.stateVerify() || !vb2.stateVerify() ||
2272 			!va15.stateVerify() || !vb15.stateVerify())
2273 		{
2274 			m_context.getTestContext().getLog()
2275 				<< tcu::TestLog::Message << "glVertexAttribPointer state change check failed."
2276 				<< tcu::TestLog::EndMessage;
2277 			status = false;
2278 		}
2279 
2280 		glBindVertexBuffer(0, m_vbo[1], 80, 24);
2281 		vb0.buffer				 = m_vbo[1];
2282 		vb0.offset				 = 80;
2283 		vb0.stride				 = 24;
2284 		va2.array_buffer_binding = m_vbo[1];
2285 		va0.array_buffer_binding = m_vbo[1];
2286 		if (!va0.stateVerify() || !vb0.stateVerify() || !va2.stateVerify() || !vb2.stateVerify() ||
2287 			!va15.stateVerify() || !vb15.stateVerify())
2288 		{
2289 			m_context.getTestContext().getLog()
2290 				<< tcu::TestLog::Message << "glBindVertexBuffer state change check failed." << tcu::TestLog::EndMessage;
2291 			status = false;
2292 		}
2293 
2294 		if (status)
2295 			return NO_ERROR;
2296 		else
2297 			return ERROR;
2298 	}
2299 };
2300 //=============================================================================
2301 // 1.6 BasicState2
2302 //-----------------------------------------------------------------------------
2303 class BasicState2 : public VertexAttribBindingBase
2304 {
2305 
2306 	GLuint m_vao;
2307 
Setup()2308 	virtual long Setup()
2309 	{
2310 		glGenVertexArrays(1, &m_vao);
2311 		return NO_ERROR;
2312 	}
2313 
Cleanup()2314 	virtual long Cleanup()
2315 	{
2316 		glDeleteVertexArrays(1, &m_vao);
2317 		return NO_ERROR;
2318 	}
2319 
Run()2320 	virtual long Run()
2321 	{
2322 		bool status = true;
2323 		glBindVertexArray(m_vao);
2324 
2325 		for (GLuint i = 0; i < 16; ++i)
2326 		{
2327 			VertexAttribState  va(i);
2328 			VertexBindingState vb(i);
2329 			glVertexAttribDivisor(i, i + 7);
2330 			va.array_divisor = i + 7;
2331 			vb.divisor		 = i + 7;
2332 			if (!va.stateVerify() || !vb.stateVerify())
2333 			{
2334 				m_context.getTestContext().getLog()
2335 					<< tcu::TestLog::Message << "glVertexAttribDivisor state change check failed."
2336 					<< tcu::TestLog::EndMessage;
2337 				status = false;
2338 			}
2339 		}
2340 		for (GLuint i = 0; i < 16; ++i)
2341 		{
2342 			VertexAttribState  va(i);
2343 			VertexBindingState vb(i);
2344 			glVertexBindingDivisor(i, i);
2345 			va.array_divisor = i;
2346 			vb.divisor		 = i;
2347 			if (!va.stateVerify() || !vb.stateVerify())
2348 			{
2349 				m_context.getTestContext().getLog()
2350 					<< tcu::TestLog::Message << "glVertexBindingDivisor state change check failed."
2351 					<< tcu::TestLog::EndMessage;
2352 				status = false;
2353 			}
2354 		}
2355 
2356 		glVertexAttribBinding(2, 5);
2357 		VertexAttribState va5(5);
2358 		va5.array_divisor = 5;
2359 		VertexBindingState vb5(5);
2360 		vb5.divisor = 5;
2361 		VertexAttribState va2(2);
2362 		va2.array_divisor = 5; // binding state seen thru mapping
2363 		VertexBindingState vb2(2);
2364 		vb2.divisor = 2;
2365 		va2.binding = 5;
2366 		if (!va5.stateVerify() || !vb5.stateVerify() || !va2.stateVerify() || !vb2.stateVerify())
2367 		{
2368 			m_context.getTestContext().getLog()
2369 				<< tcu::TestLog::Message << "glVertexAttribBinding state change check failed."
2370 				<< tcu::TestLog::EndMessage;
2371 			status = false;
2372 		}
2373 
2374 		glVertexAttribDivisor(2, 23);
2375 		va2.binding		  = 2; // glVAD defaults mapping
2376 		va2.array_divisor = 23;
2377 		vb2.divisor		  = 23;
2378 		if (!va5.stateVerify() || !vb5.stateVerify() || !va2.stateVerify() || !vb2.stateVerify())
2379 		{
2380 			m_context.getTestContext().getLog()
2381 				<< tcu::TestLog::Message << "glVertexAttribDivisor state change check failed."
2382 				<< tcu::TestLog::EndMessage;
2383 			status = false;
2384 		}
2385 
2386 		if (status)
2387 			return NO_ERROR;
2388 		else
2389 			return ERROR;
2390 	}
2391 };
2392 //=============================================================================
2393 // 2.1 AdvancedBindingUpdate
2394 //-----------------------------------------------------------------------------
2395 class AdvancedBindingUpdate : public VertexAttribBindingBase
2396 {
2397 	bool   pipeline;
2398 	GLuint m_vao[2], m_vbo[2], m_ebo[2], m_vsp, m_fsp, m_ppo;
2399 
Setup()2400 	virtual long Setup()
2401 	{
2402 		glGenVertexArrays(2, m_vao);
2403 		glGenBuffers(2, m_vbo);
2404 		glGenBuffers(2, m_ebo);
2405 		if (pipeline)
2406 		{
2407 			m_vsp = m_fsp = 0;
2408 			glGenProgramPipelines(1, &m_ppo);
2409 		}
2410 		else
2411 		{
2412 			m_ppo = 0;
2413 		}
2414 		return NO_ERROR;
2415 	}
2416 
Cleanup()2417 	virtual long Cleanup()
2418 	{
2419 		glDeleteVertexArrays(2, m_vao);
2420 		glDeleteBuffers(2, m_vbo);
2421 		glDeleteBuffers(2, m_ebo);
2422 		if (pipeline)
2423 		{
2424 			glDeleteProgram(m_vsp);
2425 			glDeleteProgram(m_fsp);
2426 			glDeleteProgramPipelines(1, &m_ppo);
2427 		}
2428 		else
2429 		{
2430 			glUseProgram(0);
2431 			glDeleteProgram(m_ppo);
2432 		}
2433 		return NO_ERROR;
2434 	}
2435 
Run()2436 	virtual long Run()
2437 	{
2438 		const char* const glsl_vs =
2439 			"#version 310 es" NL "layout(location = 0) in vec4 vs_in_position;" NL
2440 			"layout(location = 1) in vec2 vs_in_color_rg;" NL "layout(location = 2) in float vs_in_color_b;" NL
2441 			"layout(location = 3) in uvec3 vs_in_data0;" NL "layout(location = 4) in ivec2 vs_in_data1;" NL
2442 			"out vec2 color_rg;" NL "out float color_b;" NL "flat out uvec3 data0;" NL "flat out ivec2 data1;" NL
2443 			"void main() {" NL "  data0 = vs_in_data0;" NL "  data1 = vs_in_data1;" NL "  color_b = vs_in_color_b;" NL
2444 			"  color_rg = vs_in_color_rg;" NL "  gl_Position = vs_in_position;" NL "}";
2445 		const char* const glsl_fs =
2446 			"#version 310 es" NL "precision highp float;" NL "precision highp int;" NL "in vec2 color_rg;" NL
2447 			"in float color_b;" NL "flat in uvec3 data0;" NL "flat in ivec2 data1;" NL "out vec4 fs_out_color;" NL
2448 			"uniform uvec3 g_expected_data0;" NL "uniform ivec2 g_expected_data1;" NL "void main() {" NL
2449 			"  fs_out_color = vec4(color_rg, color_b, 1);" NL
2450 			"  if (data0 != g_expected_data0) fs_out_color = vec4(1);" NL
2451 			"  if (data1 != g_expected_data1) fs_out_color = vec4(1);" NL "}";
2452 		if (pipeline)
2453 		{
2454 			m_vsp = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);
2455 			m_fsp = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &glsl_fs);
2456 			if (!CheckProgram(m_vsp) || !CheckProgram(m_fsp))
2457 				return ERROR;
2458 			glUseProgramStages(m_ppo, GL_VERTEX_SHADER_BIT, m_vsp);
2459 			glUseProgramStages(m_ppo, GL_FRAGMENT_SHADER_BIT, m_fsp);
2460 		}
2461 		else
2462 		{
2463 			m_ppo			 = glCreateProgram();
2464 			const GLuint sh  = glCreateShader(GL_VERTEX_SHADER);
2465 			const GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);
2466 			glShaderSource(sh, 1, &glsl_vs, NULL);
2467 			glShaderSource(fsh, 1, &glsl_fs, NULL);
2468 			glCompileShader(sh);
2469 			glCompileShader(fsh);
2470 			glAttachShader(m_ppo, sh);
2471 			glAttachShader(m_ppo, fsh);
2472 			glDeleteShader(sh);
2473 			glDeleteShader(fsh);
2474 			glLinkProgram(m_ppo);
2475 			if (!CheckProgram(m_ppo))
2476 				return ERROR;
2477 		}
2478 
2479 		const GLsizei  kStride[2] = { 52, 64 };
2480 		const GLintptr kOffset[2] = { 0, 8 };
2481 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
2482 		/* first VBO */
2483 		{
2484 			glBufferData(GL_ARRAY_BUFFER, kOffset[0] + 4 * kStride[0], NULL, GL_STATIC_DRAW);
2485 			GLubyte* ptr = static_cast<GLubyte*>(
2486 				glMapBufferRange(GL_ARRAY_BUFFER, 0, kOffset[0] + 4 * kStride[0], GL_MAP_WRITE_BIT));
2487 			*reinterpret_cast<Vec2*>(&ptr[kOffset[0] + 0 * kStride[0]]) = Vec2(-1.0f, -1.0f);
2488 			*reinterpret_cast<Vec2*>(&ptr[kOffset[0] + 1 * kStride[0]]) = Vec2(1.0f, -1.0f);
2489 			*reinterpret_cast<Vec2*>(&ptr[kOffset[0] + 2 * kStride[0]]) = Vec2(1.0f, 1.0f);
2490 			*reinterpret_cast<Vec2*>(&ptr[kOffset[0] + 3 * kStride[0]]) = Vec2(-1.0f, 1.0f);
2491 			for (int i = 0; i < 4; ++i)
2492 			{
2493 				*reinterpret_cast<Vec2*>(&ptr[kOffset[0] + 8 + i * kStride[0]])   = Vec2(0.0f, 1.0f);
2494 				*reinterpret_cast<float*>(&ptr[kOffset[0] + 16 + i * kStride[0]]) = 0.0f;
2495 				*reinterpret_cast<UVec3*>(&ptr[kOffset[0] + 20 + i * kStride[0]]) = UVec3(1, 2, 3);
2496 				*reinterpret_cast<IVec2*>(&ptr[kOffset[0] + 44 + i * kStride[0]]) = IVec2(1, 2);
2497 			}
2498 			glUnmapBuffer(GL_ARRAY_BUFFER);
2499 		}
2500 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
2501 		/* second VBO */
2502 		{
2503 			glBufferData(GL_ARRAY_BUFFER, kOffset[1] + 4 * kStride[1], NULL, GL_STATIC_DRAW);
2504 			GLubyte* ptr = static_cast<GLubyte*>(
2505 				glMapBufferRange(GL_ARRAY_BUFFER, 0, kOffset[1] + 4 * kStride[1], GL_MAP_WRITE_BIT));
2506 			*reinterpret_cast<Vec2*>(&ptr[kOffset[1] + 0 * kStride[1]]) = Vec2(-1.0f, 1.0f);
2507 			*reinterpret_cast<Vec2*>(&ptr[kOffset[1] + 1 * kStride[1]]) = Vec2(1.0f, 1.0f);
2508 			*reinterpret_cast<Vec2*>(&ptr[kOffset[1] + 2 * kStride[1]]) = Vec2(1.0f, -1.0f);
2509 			*reinterpret_cast<Vec2*>(&ptr[kOffset[1] + 3 * kStride[1]]) = Vec2(-1.0f, -1.0f);
2510 			for (int i = 0; i < 4; ++i)
2511 			{
2512 				*reinterpret_cast<Vec2*>(&ptr[kOffset[1] + 8 + i * kStride[1]])   = Vec2(0.0f, 0.0f);
2513 				*reinterpret_cast<float*>(&ptr[kOffset[1] + 16 + i * kStride[1]]) = 1.0f;
2514 				*reinterpret_cast<UVec3*>(&ptr[kOffset[1] + 20 + i * kStride[1]]) = UVec3(4, 5, 6);
2515 				*reinterpret_cast<IVec2*>(&ptr[kOffset[1] + 44 + i * kStride[1]]) = IVec2(3, 4);
2516 			}
2517 			glUnmapBuffer(GL_ARRAY_BUFFER);
2518 		}
2519 		glBindBuffer(GL_ARRAY_BUFFER, 0);
2520 
2521 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[0]);
2522 		/* first EBO */
2523 		{
2524 			GLushort data[4] = { 0, 1, 3, 2 };
2525 			glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
2526 		}
2527 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[1]);
2528 		/* second EBO */
2529 		{
2530 			GLuint data[4] = { 3, 2, 0, 1 };
2531 			glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
2532 		}
2533 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
2534 
2535 		glBindVertexArray(m_vao[0]);
2536 		glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
2537 		glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, 8);
2538 		glVertexAttribFormat(2, 1, GL_FLOAT, GL_FALSE, 16);
2539 		glVertexAttribIFormat(3, 3, GL_UNSIGNED_INT, 20);
2540 		glVertexAttribIFormat(4, 2, GL_INT, 44);
2541 		for (GLuint i = 0; i < 5; ++i)
2542 		{
2543 			glVertexAttribBinding(i, 0);
2544 			glEnableVertexAttribArray(i);
2545 		}
2546 		glBindVertexArray(m_vao[1]);
2547 		glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
2548 		glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, 8);
2549 		glVertexAttribFormat(2, 1, GL_FLOAT, GL_FALSE, 16);
2550 		glVertexAttribIFormat(3, 3, GL_UNSIGNED_INT, 20);
2551 		glVertexAttribIFormat(4, 2, GL_INT, 44);
2552 		glVertexAttribBinding(0, 1);
2553 		glVertexAttribBinding(1, 8);
2554 		glVertexAttribBinding(2, 1);
2555 		glVertexAttribBinding(3, 1);
2556 		glVertexAttribBinding(4, 8);
2557 		glEnableVertexAttribArray(0);
2558 		glEnableVertexAttribArray(1);
2559 		glEnableVertexAttribArray(2);
2560 		glEnableVertexAttribArray(3);
2561 		glEnableVertexAttribArray(4);
2562 		glBindVertexBuffer(1, m_vbo[1], kOffset[1], kStride[1]);
2563 		glBindVertexBuffer(8, m_vbo[0], kOffset[0], kStride[0]);
2564 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[1]);
2565 		glBindVertexArray(0);
2566 
2567 		glClear(GL_COLOR_BUFFER_BIT);
2568 		GLuint ppo;
2569 		if (pipeline)
2570 		{
2571 			glBindProgramPipeline(m_ppo);
2572 			ppo = m_fsp;
2573 		}
2574 		else
2575 		{
2576 			glUseProgram(m_ppo);
2577 			ppo = m_ppo;
2578 		}
2579 		glBindVertexArray(m_vao[0]);
2580 
2581 		// Bind first VBO
2582 		glProgramUniform3ui(ppo, glGetUniformLocation(ppo, "g_expected_data0"), 1, 2, 3);
2583 		glProgramUniform2i(ppo, glGetUniformLocation(ppo, "g_expected_data1"), 1, 2);
2584 		glBindVertexBuffer(0, m_vbo[0], kOffset[0], kStride[0]);
2585 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[0]);
2586 		glDrawElementsInstanced(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1);
2587 
2588 		bool status = true;
2589 		if (!CheckFB(Vec3(0, 1, 0)))
2590 			status = false;
2591 		if (!status)
2592 			return ERROR;
2593 
2594 		// Bind second VBO (change all vertex attribs with one call)
2595 		glProgramUniform3ui(ppo, glGetUniformLocation(ppo, "g_expected_data0"), 4, 5, 6);
2596 		glProgramUniform2i(ppo, glGetUniformLocation(ppo, "g_expected_data1"), 3, 4);
2597 
2598 		glBindVertexBuffer(0, m_vbo[1], kOffset[1], kStride[1]);
2599 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[1]);
2600 		glDrawElementsInstanced(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0, 1);
2601 
2602 		if (!CheckFB(Vec3(0, 0, 1)))
2603 			status = false;
2604 		if (!status)
2605 			return ERROR;
2606 
2607 		// Change attrib bindings (all attribs from one buffer)
2608 		glBindVertexBuffer(0, 0, 0, 0); // "unbind" buffer
2609 
2610 		glProgramUniform3ui(ppo, glGetUniformLocation(ppo, "g_expected_data0"), 1, 2, 3);
2611 		glProgramUniform2i(ppo, glGetUniformLocation(ppo, "g_expected_data1"), 1, 2);
2612 
2613 		for (GLuint i = 0; i < 5; ++i)
2614 			glVertexAttribBinding(i, 15);
2615 		glBindVertexBuffer(15, m_vbo[0], kOffset[0], kStride[0]);
2616 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[0]);
2617 		glDrawElementsInstanced(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1);
2618 
2619 		if (!CheckFB(Vec3(0, 1, 0)))
2620 			status = false;
2621 		if (!status)
2622 			return ERROR;
2623 
2624 		// Change attrib bindings (attribs from two buffers)
2625 		glBindVertexBuffer(15, 0, 0, 0); // "unbind" buffer
2626 
2627 		glProgramUniform3ui(ppo, glGetUniformLocation(ppo, "g_expected_data0"), 1, 2, 3);
2628 		glProgramUniform2i(ppo, glGetUniformLocation(ppo, "g_expected_data1"), 3, 4);
2629 
2630 		glBindVertexBuffer(7, m_vbo[0], kOffset[0], kStride[0]);
2631 		glBindVertexBuffer(12, m_vbo[1], kOffset[1], kStride[1]);
2632 		glVertexAttribBinding(0, 7);
2633 		glVertexAttribBinding(1, 12);
2634 		glVertexAttribBinding(2, 12);
2635 		glVertexAttribBinding(3, 7);
2636 		glVertexAttribBinding(4, 12);
2637 		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[0]);
2638 		glDrawElementsInstanced(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1);
2639 
2640 		if (!CheckFB(Vec3(0, 0, 1)))
2641 			status = false;
2642 		if (!status)
2643 			return ERROR;
2644 
2645 		// Disable one of the attribs
2646 		glClear(GL_COLOR_BUFFER_BIT);
2647 		glProgramUniform2i(ppo, glGetUniformLocation(ppo, "g_expected_data1"), 0, 0);
2648 		glDisableVertexAttribArray(4);
2649 		glVertexAttribI4i(4, 0, 0, 0, 0);
2650 		glDrawElementsInstanced(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1);
2651 
2652 		if (!CheckFB(Vec3(0, 0, 1)))
2653 			status = false;
2654 		if (!status)
2655 			return ERROR;
2656 
2657 		// Change VAO
2658 		glProgramUniform3ui(ppo, glGetUniformLocation(ppo, "g_expected_data0"), 4, 5, 6);
2659 		glProgramUniform2i(ppo, glGetUniformLocation(ppo, "g_expected_data1"), 1, 2);
2660 
2661 		glBindVertexArray(m_vao[1]);
2662 		glDrawElementsInstanced(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0, 1);
2663 
2664 		if (!CheckFB(Vec3(0, 1, 1)))
2665 			status = false;
2666 		if (!status)
2667 			return ERROR;
2668 
2669 		return NO_ERROR;
2670 	}
2671 
2672 public:
AdvancedBindingUpdate()2673 	AdvancedBindingUpdate() : pipeline(true)
2674 	{
2675 	}
2676 };
2677 //=============================================================================
2678 // 2.3 AdvancedIterations
2679 //-----------------------------------------------------------------------------
2680 class AdvancedIterations : public VertexAttribBindingBase
2681 {
2682 
2683 	GLuint m_po, m_vao[2], m_buffer[2];
2684 
Setup()2685 	virtual long Setup()
2686 	{
2687 		m_po = 0;
2688 		glGenVertexArrays(2, m_vao);
2689 		glGenBuffers(2, m_buffer);
2690 		return NO_ERROR;
2691 	}
2692 
Cleanup()2693 	virtual long Cleanup()
2694 	{
2695 		glDisable(GL_RASTERIZER_DISCARD);
2696 		glUseProgram(0);
2697 		glDeleteProgram(m_po);
2698 		glDeleteVertexArrays(2, m_vao);
2699 		glDeleteBuffers(2, m_buffer);
2700 		return NO_ERROR;
2701 	}
2702 
Run()2703 	virtual long Run()
2704 	{
2705 		const char* const glsl_vs = "#version 310 es" NL "in ivec4 vs_in_data;" NL "flat out ivec4 data;" NL
2706 									"void main() {" NL "  data = vs_in_data + 1;" NL "}";
2707 		const char* const glsl_fs =
2708 			"#version 310 es" NL "precision mediump float;" NL "flat in ivec4 data;" NL "out vec4 fs_out_color;" NL
2709 			"void main() {" NL "  fs_out_color = vec4(data);" NL "}";
2710 		m_po = glCreateProgram();
2711 		/* attach shader */
2712 		{
2713 			const GLuint sh  = glCreateShader(GL_VERTEX_SHADER);
2714 			const GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);
2715 			glShaderSource(sh, 1, &glsl_vs, NULL);
2716 			glShaderSource(fsh, 1, &glsl_fs, NULL);
2717 			glCompileShader(sh);
2718 			glCompileShader(fsh);
2719 			glAttachShader(m_po, sh);
2720 			glAttachShader(m_po, fsh);
2721 			glDeleteShader(sh);
2722 			glDeleteShader(fsh);
2723 		}
2724 		if (!RelinkProgram(1))
2725 			return ERROR;
2726 
2727 		glBindBuffer(GL_ARRAY_BUFFER, m_buffer[0]);
2728 		IVec4 zero(0);
2729 		glBufferData(GL_ARRAY_BUFFER, 16, &zero, GL_STATIC_DRAW);
2730 		glBindBuffer(GL_ARRAY_BUFFER, 0);
2731 
2732 		glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer[1]);
2733 		glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, &zero, GL_DYNAMIC_READ);
2734 		glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
2735 
2736 		glBindVertexArray(m_vao[0]);
2737 		glVertexAttribIFormat(1, 4, GL_INT, 0);
2738 		glEnableVertexAttribArray(1);
2739 		glBindVertexBuffer(1, m_buffer[0], 0, 16);
2740 		glBindVertexArray(m_vao[1]);
2741 		glVertexAttribIFormat(1, 4, GL_INT, 0);
2742 		glEnableVertexAttribArray(1);
2743 		glBindVertexBuffer(1, m_buffer[1], 0, 16);
2744 		glBindVertexArray(0);
2745 		glEnable(GL_RASTERIZER_DISCARD);
2746 		glUseProgram(m_po);
2747 
2748 		for (int i = 0; i < 10; ++i)
2749 		{
2750 			glBindVertexArray(m_vao[i % 2]);
2751 			glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer[(i + 1) % 2]);
2752 			glBeginTransformFeedback(GL_POINTS);
2753 			glDrawArrays(GL_POINTS, 0, 1);
2754 			glEndTransformFeedback();
2755 		}
2756 		/* */
2757 		{
2758 			IVec4* data =
2759 				static_cast<IVec4*>(glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(IVec4), GL_MAP_READ_BIT));
2760 			if (!IsEqual(*data, IVec4(10)))
2761 			{
2762 				m_context.getTestContext().getLog()
2763 					<< tcu::TestLog::Message << "Data is: " << (*data)[0] << " " << (*data)[1] << " " << (*data)[2]
2764 					<< " " << (*data)[3] << ", data should be: 10 10 10 10." << tcu::TestLog::EndMessage;
2765 				return ERROR;
2766 			}
2767 			glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
2768 		}
2769 
2770 		if (!RelinkProgram(5))
2771 			return ERROR;
2772 		glBindVertexArray(m_vao[0]);
2773 		glDisableVertexAttribArray(1);
2774 		glBindVertexBuffer(1, 0, 0, 0);
2775 		glVertexAttribIFormat(5, 4, GL_INT, 0);
2776 		glEnableVertexAttribArray(5);
2777 		glBindVertexBuffer(5, m_buffer[0], 0, 16);
2778 		glBindVertexArray(m_vao[1]);
2779 		glDisableVertexAttribArray(1);
2780 		glBindVertexBuffer(1, 0, 0, 0);
2781 		glVertexAttribIFormat(5, 4, GL_INT, 0);
2782 		glEnableVertexAttribArray(5);
2783 		glBindVertexBuffer(7, m_buffer[1], 0, 16);
2784 		glVertexAttribBinding(5, 7);
2785 		glBindVertexArray(0);
2786 
2787 		for (int i = 0; i < 10; ++i)
2788 		{
2789 			glBindVertexArray(m_vao[i % 2]);
2790 			glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer[(i + 1) % 2]);
2791 			glBeginTransformFeedback(GL_POINTS);
2792 			glDrawArrays(GL_POINTS, 0, 1);
2793 			glEndTransformFeedback();
2794 		}
2795 		/* */
2796 		{
2797 			IVec4* data =
2798 				static_cast<IVec4*>(glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(IVec4), GL_MAP_READ_BIT));
2799 			if (!IsEqual(*data, IVec4(20)))
2800 			{
2801 				m_context.getTestContext().getLog()
2802 					<< tcu::TestLog::Message << "Data is: " << (*data)[0] << " " << (*data)[1] << " " << (*data)[2]
2803 					<< " " << (*data)[3] << ", data should be: 20 20 20 20." << tcu::TestLog::EndMessage;
2804 				return ERROR;
2805 			}
2806 			glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
2807 		}
2808 
2809 		if (!RelinkProgram(11))
2810 			return ERROR;
2811 		glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
2812 		glBindVertexArray(m_vao[0]);
2813 		glDisableVertexAttribArray(5);
2814 		glBindVertexBuffer(5, 0, 0, 0);
2815 		glVertexAttribIFormat(11, 4, GL_INT, 0);
2816 		glEnableVertexAttribArray(11);
2817 		for (int i = 0; i < 10; ++i)
2818 		{
2819 			glBindVertexBuffer(11, m_buffer[i % 2], 0, 16);
2820 			glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer[(i + 1) % 2]);
2821 			glBeginTransformFeedback(GL_POINTS);
2822 			glDrawArrays(GL_POINTS, 0, 1);
2823 			glEndTransformFeedback();
2824 		}
2825 		/* */
2826 		{
2827 			IVec4* data =
2828 				static_cast<IVec4*>(glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(IVec4), GL_MAP_READ_BIT));
2829 			if (!IsEqual(*data, IVec4(30)))
2830 			{
2831 				m_context.getTestContext().getLog()
2832 					<< tcu::TestLog::Message << "Data is: " << (*data)[0] << " " << (*data)[1] << " " << (*data)[2]
2833 					<< " " << (*data)[3] << ", data should be: 30 30 30 30." << tcu::TestLog::EndMessage;
2834 				return ERROR;
2835 			}
2836 		}
2837 
2838 		return NO_ERROR;
2839 	}
2840 
RelinkProgram(GLuint index)2841 	bool RelinkProgram(GLuint index)
2842 	{
2843 		glBindAttribLocation(m_po, index, "vs_in_data");
2844 		/* setup XFB */
2845 		{
2846 			const GLchar* const v[1] = { "data" };
2847 			glTransformFeedbackVaryings(m_po, 1, v, GL_INTERLEAVED_ATTRIBS);
2848 		}
2849 		glLinkProgram(m_po);
2850 		if (!CheckProgram(m_po))
2851 			return false;
2852 		return true;
2853 	}
2854 };
2855 //=============================================================================
2856 // 2.4 AdvancedLargeStrideAndOffsetsNewAndLegacyAPI
2857 //-----------------------------------------------------------------------------
2858 class AdvancedLargeStrideAndOffsetsNewAndLegacyAPI : public VertexAttribBindingBase
2859 {
2860 	bool   pipeline;
2861 	GLuint m_vsp, m_fsp, m_ppo, m_ssbo, m_vao, m_vbo;
2862 
Setup()2863 	virtual long Setup()
2864 	{
2865 		m_vsp = 0;
2866 		if (pipeline)
2867 		{
2868 			m_vsp = m_fsp = 0;
2869 			glGenProgramPipelines(1, &m_ppo);
2870 		}
2871 		else
2872 		{
2873 			m_ppo = 0;
2874 		}
2875 		glGenBuffers(1, &m_ssbo);
2876 		glGenVertexArrays(1, &m_vao);
2877 		glGenBuffers(1, &m_vbo);
2878 		return NO_ERROR;
2879 	}
2880 
Cleanup()2881 	virtual long Cleanup()
2882 	{
2883 		glDisable(GL_RASTERIZER_DISCARD);
2884 		if (pipeline)
2885 		{
2886 			glDeleteProgram(m_vsp);
2887 			glDeleteProgram(m_fsp);
2888 			glDeleteProgramPipelines(1, &m_ppo);
2889 		}
2890 		else
2891 		{
2892 			glUseProgram(0);
2893 			glDeleteProgram(m_ppo);
2894 		}
2895 		glDeleteBuffers(1, &m_ssbo);
2896 		glDeleteVertexArrays(1, &m_vao);
2897 		glDeleteBuffers(1, &m_vbo);
2898 		return NO_ERROR;
2899 	}
2900 
Run()2901 	virtual long Run()
2902 	{
2903 		if (!IsSSBOInVSFSAvailable(2))
2904 			return NOT_SUPPORTED;
2905 		const char* const glsl_vs =
2906 			"#version 310 es" NL "layout(location = 0) in vec2 vs_in_attrib0;" NL
2907 			"layout(location = 4) in ivec2 vs_in_attrib1;" NL "layout(location = 8) in uvec2 vs_in_attrib2;" NL
2908 			"layout(location = 15) in float vs_in_attrib3;" NL "layout(std430, binding = 1) buffer Output {" NL
2909 			"  vec2 attrib0[4];" NL "  ivec2 attrib1[4];" NL "  uvec2 attrib2[4];" NL "  float attrib3[4];" NL
2910 			"} g_output;" NL "void main() {" NL
2911 			"  g_output.attrib0[2 * gl_InstanceID + gl_VertexID] = vs_in_attrib0;" NL
2912 			"  g_output.attrib1[2 * gl_InstanceID + gl_VertexID] = vs_in_attrib1;" NL
2913 			"  g_output.attrib2[2 * gl_InstanceID + gl_VertexID] = vs_in_attrib2;" NL
2914 			"  g_output.attrib3[2 * gl_InstanceID + gl_VertexID] = vs_in_attrib3;" NL "}";
2915 		const char* const glsl_fs = "#version 310 es" NL "precision mediump float;" NL "out vec4 fs_out_color;" NL
2916 									"void main() {" NL "  fs_out_color = vec4(0.5,0.5,0.5,1.0);" NL "}";
2917 		if (pipeline)
2918 		{
2919 			m_vsp = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);
2920 			m_fsp = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &glsl_fs);
2921 			if (!CheckProgram(m_vsp) || !CheckProgram(m_fsp))
2922 				return ERROR;
2923 			glUseProgramStages(m_ppo, GL_VERTEX_SHADER_BIT, m_vsp);
2924 			glUseProgramStages(m_ppo, GL_FRAGMENT_SHADER_BIT, m_fsp);
2925 		}
2926 		else
2927 		{
2928 			m_ppo			 = glCreateProgram();
2929 			const GLuint sh  = glCreateShader(GL_VERTEX_SHADER);
2930 			const GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);
2931 			glShaderSource(sh, 1, &glsl_vs, NULL);
2932 			glShaderSource(fsh, 1, &glsl_fs, NULL);
2933 			glCompileShader(sh);
2934 			glCompileShader(fsh);
2935 			glAttachShader(m_ppo, sh);
2936 			glAttachShader(m_ppo, fsh);
2937 			glDeleteShader(sh);
2938 			glDeleteShader(fsh);
2939 			glLinkProgram(m_ppo);
2940 			if (!CheckProgram(m_ppo))
2941 				return ERROR;
2942 		}
2943 
2944 		/* vbo */
2945 		{
2946 			glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
2947 			glBufferData(GL_ARRAY_BUFFER, 100000, NULL, GL_STATIC_DRAW);
2948 			GLubyte* ptr = static_cast<GLubyte*>(glMapBufferRange(GL_ARRAY_BUFFER, 0, 100000, GL_MAP_WRITE_BIT));
2949 			// attrib0
2950 			*reinterpret_cast<Vec2*>(&ptr[16 + 0 * 2048]) = Vec2(1.0f, 2.0f);
2951 			*reinterpret_cast<Vec2*>(&ptr[16 + 1 * 2048]) = Vec2(3.0f, 4.0f);
2952 			// attrib1
2953 			*reinterpret_cast<IVec2*>(&ptr[128 + 0 * 2048]) = IVec2(5, 6);
2954 			*reinterpret_cast<IVec2*>(&ptr[128 + 1 * 2048]) = IVec2(7, 8);
2955 			// attrib2
2956 			*reinterpret_cast<UVec2*>(&ptr[1024 + 0 * 2048]) = UVec2(9, 10);
2957 			*reinterpret_cast<UVec2*>(&ptr[1024 + 1 * 2048]) = UVec2(11, 12);
2958 			// attrib3
2959 			*reinterpret_cast<float*>(&ptr[2032 + 0 * 2048]) = 13.0f;
2960 			*reinterpret_cast<float*>(&ptr[2032 + 1 * 2048]) = 14.0f;
2961 			glUnmapBuffer(GL_ARRAY_BUFFER);
2962 			glBindBuffer(GL_ARRAY_BUFFER, 0);
2963 		}
2964 		// vao
2965 		glBindVertexArray(m_vao);
2966 		glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 16);
2967 		glVertexAttribIFormat(8, 2, GL_UNSIGNED_INT, 1024);
2968 		glVertexAttribFormat(15, 1, GL_FLOAT, GL_FALSE, 2032);
2969 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
2970 		glVertexAttribIPointer(4, 2, GL_INT, 2048, reinterpret_cast<void*>(128));
2971 		glBindBuffer(GL_ARRAY_BUFFER, 0);
2972 		glVertexAttribBinding(8, 3);
2973 		glVertexAttribBinding(15, 3);
2974 		glBindVertexBuffer(0, m_vbo, 0, 2048);
2975 		glBindVertexBuffer(3, m_vbo, 0, 2048);
2976 		glEnableVertexAttribArray(0);
2977 		glEnableVertexAttribArray(4);
2978 		glEnableVertexAttribArray(8);
2979 		glEnableVertexAttribArray(15);
2980 		glBindVertexArray(0);
2981 
2982 		// ssbo
2983 		std::vector<GLubyte> data((sizeof(Vec2) + sizeof(IVec2) + sizeof(UVec2) + sizeof(float)) * 4, 0xff);
2984 		glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_ssbo);
2985 		glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)data.size(), &data[0], GL_DYNAMIC_DRAW);
2986 
2987 		glEnable(GL_RASTERIZER_DISCARD);
2988 		if (pipeline)
2989 			glBindProgramPipeline(m_ppo);
2990 		else
2991 			glUseProgram(m_ppo);
2992 		glBindVertexArray(m_vao);
2993 		glDrawArraysInstanced(GL_POINTS, 0, 2, 2);
2994 
2995 		/* */
2996 		{
2997 			glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_ssbo);
2998 			GLubyte* ptr = static_cast<GLubyte*>(
2999 				glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, (GLsizeiptr)data.size(), GL_MAP_READ_BIT));
3000 			// attrib0
3001 			Vec2 i0_v0_a0 = *reinterpret_cast<Vec2*>(&ptr[0]);
3002 			Vec2 i0_v1_a0 = *reinterpret_cast<Vec2*>(&ptr[8]);
3003 			Vec2 i1_v0_a0 = *reinterpret_cast<Vec2*>(&ptr[16]);
3004 			Vec2 i1_v1_a0 = *reinterpret_cast<Vec2*>(&ptr[24]);
3005 			if (!IsEqual(i0_v0_a0, Vec2(1.0f, 2.0f)))
3006 				return ERROR;
3007 			if (!IsEqual(i0_v1_a0, Vec2(3.0f, 4.0f)))
3008 				return ERROR;
3009 			if (!IsEqual(i1_v0_a0, Vec2(1.0f, 2.0f)))
3010 				return ERROR;
3011 			if (!IsEqual(i1_v1_a0, Vec2(3.0f, 4.0f)))
3012 				return ERROR;
3013 			// attrib1
3014 			IVec2 i0_v0_a1 = *reinterpret_cast<IVec2*>(&ptr[32]);
3015 			IVec2 i0_v1_a1 = *reinterpret_cast<IVec2*>(&ptr[40]);
3016 			IVec2 i1_v0_a1 = *reinterpret_cast<IVec2*>(&ptr[48]);
3017 			IVec2 i1_v1_a1 = *reinterpret_cast<IVec2*>(&ptr[56]);
3018 			if (!IsEqual(i0_v0_a1, IVec2(5, 6)))
3019 				return ERROR;
3020 			if (!IsEqual(i0_v1_a1, IVec2(7, 8)))
3021 				return ERROR;
3022 			if (!IsEqual(i1_v0_a1, IVec2(5, 6)))
3023 				return ERROR;
3024 			if (!IsEqual(i1_v1_a1, IVec2(7, 8)))
3025 				return ERROR;
3026 			// attrib2
3027 			UVec2 i0_v0_a2 = *reinterpret_cast<UVec2*>(&ptr[64]);
3028 			UVec2 i0_v1_a2 = *reinterpret_cast<UVec2*>(&ptr[72]);
3029 			UVec2 i1_v0_a2 = *reinterpret_cast<UVec2*>(&ptr[80]);
3030 			UVec2 i1_v1_a2 = *reinterpret_cast<UVec2*>(&ptr[88]);
3031 			if (!IsEqual(i0_v0_a2, UVec2(9, 10)))
3032 				return ERROR;
3033 			if (!IsEqual(i0_v1_a2, UVec2(11, 12)))
3034 				return ERROR;
3035 			if (!IsEqual(i1_v0_a2, UVec2(9, 10)))
3036 				return ERROR;
3037 			if (!IsEqual(i1_v1_a2, UVec2(11, 12)))
3038 				return ERROR;
3039 			// attrib3
3040 			float i0_v0_a3 = *reinterpret_cast<float*>(&ptr[96]);
3041 			float i0_v1_a3 = *reinterpret_cast<float*>(&ptr[100]);
3042 			float i1_v0_a3 = *reinterpret_cast<float*>(&ptr[104]);
3043 			float i1_v1_a3 = *reinterpret_cast<float*>(&ptr[108]);
3044 			if (i0_v0_a3 != 13.0f)
3045 				return ERROR;
3046 			if (i0_v1_a3 != 14.0f)
3047 				return ERROR;
3048 			if (i1_v0_a3 != 13.0f)
3049 				return ERROR;
3050 			if (i1_v1_a3 != 14.0f)
3051 				return ERROR;
3052 			glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
3053 		}
3054 		return NO_ERROR;
3055 	}
3056 
3057 public:
AdvancedLargeStrideAndOffsetsNewAndLegacyAPI()3058 	AdvancedLargeStrideAndOffsetsNewAndLegacyAPI() : pipeline(true)
3059 	{
3060 	}
3061 };
3062 //=============================================================================
3063 // 4.1 NegativeBindVertexBuffer
3064 //-----------------------------------------------------------------------------
3065 class NegativeBindVertexBuffer : public VertexAttribBindingBase
3066 {
3067 
3068 	GLuint m_vao, m_vbo;
3069 
Setup()3070 	virtual long Setup()
3071 	{
3072 		glGenVertexArrays(1, &m_vao);
3073 		glGenBuffers(1, &m_vbo);
3074 		return NO_ERROR;
3075 	}
3076 
Cleanup()3077 	virtual long Cleanup()
3078 	{
3079 		glDeleteVertexArrays(1, &m_vao);
3080 		glDeleteBuffers(1, &m_vbo);
3081 		return NO_ERROR;
3082 	}
3083 
Run()3084 	virtual long Run()
3085 	{
3086 		/*
3087 		 Errors
3088 		 An INVALID_OPERATION error is generated if buffer is not zero or a name
3089 		 returned from a previous call to GenBuffers, or if such a name has since been
3090 		 deleted with DeleteBuffers.
3091 		 An INVALID_VALUE error is generated if bindingindex is greater than or
3092 		 equal to the value of MAX_VERTEX_ATTRIB_BINDINGS.
3093 		 OpenGL 4.4 (Core Profile) - July 21, 2013
3094 		 10.3. VERTEX ARRAYS 315
3095 		 An INVALID_VALUE error is generated if stride or offset is negative, or if
3096 		 stride is greater than the value of MAX_VERTEX_ATTRIB_STRIDE.
3097 		 An INVALID_OPERATION error is generated if no vertex array object is
3098 		 bound.
3099 		 */
3100 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
3101 		glBufferData(GL_ARRAY_BUFFER, 1000, NULL, GL_STATIC_DRAW);
3102 		glBindBuffer(GL_ARRAY_BUFFER, 0);
3103 
3104 		glBindVertexArray(m_vao);
3105 
3106 		glBindVertexBuffer(0, 1234, 0, 12);
3107 		if (glGetError() != GL_INVALID_OPERATION)
3108 		{
3109 			m_context.getTestContext().getLog()
3110 				<< tcu::TestLog::Message << "INVALID_OPERATION should be generated (buffer name not genned)."
3111 				<< tcu::TestLog::EndMessage;
3112 			return ERROR;
3113 		}
3114 
3115 		GLint p;
3116 		glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &p);
3117 		glBindVertexBuffer(p + 1, m_vbo, 0, 12);
3118 		if (glGetError() != GL_INVALID_VALUE)
3119 		{
3120 			m_context.getTestContext().getLog()
3121 				<< tcu::TestLog::Message
3122 				<< "INVALID_VALUE should be generated (bindingIndex greater than GL_MAX_VERTEX_ATTRIB_BINDINGS)."
3123 				<< tcu::TestLog::EndMessage;
3124 			return ERROR;
3125 		}
3126 
3127 		glBindVertexBuffer(0, m_vbo, -10, 12);
3128 		if (glGetError() != GL_INVALID_VALUE)
3129 		{
3130 			m_context.getTestContext().getLog()
3131 				<< tcu::TestLog::Message << "INVALID_VALUE should be generated (negative offset)."
3132 				<< tcu::TestLog::EndMessage;
3133 			return ERROR;
3134 		}
3135 		glBindVertexBuffer(0, m_vbo, 0, -12);
3136 		if (glGetError() != GL_INVALID_VALUE)
3137 		{
3138 			m_context.getTestContext().getLog()
3139 				<< tcu::TestLog::Message << "INVALID_VALUE should be generated (negative stride)."
3140 				<< tcu::TestLog::EndMessage;
3141 			return ERROR;
3142 		}
3143 
3144 		glGetIntegerv(GL_MAX_VERTEX_ATTRIB_STRIDE, &p);
3145 		glBindVertexBuffer(0, m_vbo, 0, p + 4);
3146 		if (glGetError() != GL_INVALID_VALUE)
3147 		{
3148 			m_context.getTestContext().getLog()
3149 				<< tcu::TestLog::Message
3150 				<< "INVALID_VALUE should be generated (stride greater than GL_MAX_VERTEX_ATTRIB_STRIDE)."
3151 				<< tcu::TestLog::EndMessage;
3152 			return ERROR;
3153 		}
3154 
3155 		glBindVertexArray(0);
3156 		glBindVertexBuffer(0, m_vbo, 0, 12);
3157 		if (glGetError() != GL_INVALID_OPERATION)
3158 		{
3159 			m_context.getTestContext().getLog()
3160 				<< tcu::TestLog::Message << "INVALID_OPERATION should be generated (default VAO)."
3161 				<< tcu::TestLog::EndMessage;
3162 			return ERROR;
3163 		}
3164 
3165 		return NO_ERROR;
3166 	}
3167 };
3168 //=============================================================================
3169 // 4.2 NegativeVertexAttribFormat
3170 //-----------------------------------------------------------------------------
3171 class NegativeVertexAttribFormat : public VertexAttribBindingBase
3172 {
3173 
3174 	GLuint m_vao, m_vbo;
3175 
Setup()3176 	virtual long Setup()
3177 	{
3178 		glGenVertexArrays(1, &m_vao);
3179 		glGenBuffers(1, &m_vbo);
3180 		return NO_ERROR;
3181 	}
3182 
Cleanup()3183 	virtual long Cleanup()
3184 	{
3185 		glDeleteVertexArrays(1, &m_vao);
3186 		glDeleteBuffers(1, &m_vbo);
3187 		return NO_ERROR;
3188 	}
3189 
Run()3190 	virtual long Run()
3191 	{
3192 		/*
3193 		 Errors
3194 		 An INVALID_VALUE error is generated if attribindex is greater than or
3195 		 equal to the value of MAX_VERTEX_ATTRIBS.
3196 		 An INVALID_VALUE error is generated if size is not one of the values
3197 		 shown in table 10.2 for the corresponding command.
3198 		 An INVALID_ENUM error is generated if type is not one of the parameter
3199 		 token names from table 8.2 corresponding to one of the allowed GL data types
3200 		 for that command as shown in table 10.2.
3201 		 An INVALID_OPERATION error is generated under any of the following
3202 		 conditions:
3203 		 - if no vertex array object is currently bound (see section 10.4);
3204 		 - type is INT_2_10_10_10_REV or UNSIGNED_INT_2_10_10_10_-
3205 		 REV, and size is not 4;
3206 		 An INVALID_VALUE error is generated if relativeoffset is larger than the
3207 		 value of MAX_VERTEX_ATTRIB_RELATIVE_OFFSET.
3208 		 */
3209 		glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
3210 		glBufferData(GL_ARRAY_BUFFER, 1000, NULL, GL_STATIC_DRAW);
3211 		glBindBuffer(GL_ARRAY_BUFFER, 0);
3212 
3213 		glBindVertexArray(m_vao);
3214 
3215 		GLint p;
3216 		glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &p);
3217 		glVertexAttribFormat(p + 1, 4, GL_FLOAT, GL_FALSE, 0);
3218 		if (glGetError() != GL_INVALID_VALUE)
3219 		{
3220 			m_context.getTestContext().getLog()
3221 				<< tcu::TestLog::Message
3222 				<< "INVALID_VALUE should be generated (attribindex greater than GL_MAX_VERTEX_ATTRIBS)."
3223 				<< tcu::TestLog::EndMessage;
3224 			return ERROR;
3225 		}
3226 		glVertexAttribIFormat(p + 2, 4, GL_INT, 0);
3227 		if (glGetError() != GL_INVALID_VALUE)
3228 		{
3229 			m_context.getTestContext().getLog()
3230 				<< tcu::TestLog::Message
3231 				<< "INVALID_VALUE should be generated (attribindex greater than GL_MAX_VERTEX_ATTRIBS)."
3232 				<< tcu::TestLog::EndMessage;
3233 			return ERROR;
3234 		}
3235 		glVertexAttribFormat(0, 0, GL_FLOAT, GL_FALSE, 0);
3236 		if (glGetError() != GL_INVALID_VALUE)
3237 		{
3238 			m_context.getTestContext().getLog()
3239 				<< tcu::TestLog::Message << "INVALID_VALUE should be generated (invalid number of components)."
3240 				<< tcu::TestLog::EndMessage;
3241 			return ERROR;
3242 		}
3243 		glVertexAttribFormat(0, 5, GL_FLOAT, GL_FALSE, 0);
3244 		if (glGetError() != GL_INVALID_VALUE)
3245 		{
3246 			m_context.getTestContext().getLog()
3247 				<< tcu::TestLog::Message << "INVALID_VALUE should be generated (invalid number of components)."
3248 				<< tcu::TestLog::EndMessage;
3249 			return ERROR;
3250 		}
3251 		glVertexAttribIFormat(0, 5, GL_INT, 0);
3252 		if (glGetError() != GL_INVALID_VALUE)
3253 		{
3254 			m_context.getTestContext().getLog()
3255 				<< tcu::TestLog::Message << "INVALID_VALUE should be generated (invalid number of components)."
3256 				<< tcu::TestLog::EndMessage;
3257 			return ERROR;
3258 		}
3259 		glVertexAttribFormat(0, 4, GL_R32F, GL_FALSE, 0);
3260 		if (glGetError() != GL_INVALID_ENUM)
3261 		{
3262 			m_context.getTestContext().getLog()
3263 				<< tcu::TestLog::Message << "INVALID_ENUM should be generated (invalid type)."
3264 				<< tcu::TestLog::EndMessage;
3265 			return ERROR;
3266 		}
3267 		glVertexAttribIFormat(0, 4, GL_FLOAT, 0);
3268 		if (glGetError() != GL_INVALID_ENUM)
3269 		{
3270 			m_context.getTestContext().getLog()
3271 				<< tcu::TestLog::Message << "INVALID_ENUM should be generated (invalid type)."
3272 				<< tcu::TestLog::EndMessage;
3273 			return ERROR;
3274 		}
3275 		glVertexAttribFormat(0, 3, GL_INT_2_10_10_10_REV, GL_FALSE, 0);
3276 		if (glGetError() != GL_INVALID_OPERATION)
3277 		{
3278 			m_context.getTestContext().getLog()
3279 				<< tcu::TestLog::Message
3280 				<< "INVALID_OPERATION should be generated (invalid number of components for packed type)."
3281 				<< tcu::TestLog::EndMessage;
3282 			return ERROR;
3283 		}
3284 		glGetIntegerv(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
3285 		glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, p + 10);
3286 		if (glGetError() != GL_INVALID_VALUE)
3287 		{
3288 			m_context.getTestContext().getLog()
3289 				<< tcu::TestLog::Message << "INVALID_VALUE should be generated (relativeoffset greater than "
3290 											"GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET)."
3291 				<< tcu::TestLog::EndMessage;
3292 			return ERROR;
3293 		}
3294 		glVertexAttribIFormat(0, 4, GL_INT, p + 10);
3295 		if (glGetError() != GL_INVALID_VALUE)
3296 		{
3297 			m_context.getTestContext().getLog()
3298 				<< tcu::TestLog::Message << "INVALID_VALUE should be generated (relativeoffset greater than "
3299 											"GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET)."
3300 				<< tcu::TestLog::EndMessage;
3301 			return ERROR;
3302 		}
3303 		glBindVertexArray(0);
3304 		glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, 0);
3305 		if (glGetError() != GL_INVALID_OPERATION)
3306 		{
3307 			m_context.getTestContext().getLog()
3308 				<< tcu::TestLog::Message << "INVALID_OPERATION should be generated (default VAO)."
3309 				<< tcu::TestLog::EndMessage;
3310 			return ERROR;
3311 		}
3312 		glVertexAttribIFormat(0, 4, GL_INT, 0);
3313 		if (glGetError() != GL_INVALID_OPERATION)
3314 		{
3315 			m_context.getTestContext().getLog()
3316 				<< tcu::TestLog::Message << "INVALID_OPERATION should be generated (default VAO)."
3317 				<< tcu::TestLog::EndMessage;
3318 			return ERROR;
3319 		}
3320 		return NO_ERROR;
3321 	}
3322 };
3323 
3324 //=============================================================================
3325 // 4.3 NegativeVertexAttribBinding
3326 //-----------------------------------------------------------------------------
3327 class NegativeVertexAttribBinding : public VertexAttribBindingBase
3328 {
3329 	GLuint m_vao;
3330 
Setup()3331 	virtual long Setup()
3332 	{
3333 		glGenVertexArrays(1, &m_vao);
3334 		return NO_ERROR;
3335 	}
3336 
Cleanup()3337 	virtual long Cleanup()
3338 	{
3339 		glDeleteVertexArrays(1, &m_vao);
3340 		return NO_ERROR;
3341 	}
3342 
Run()3343 	virtual long Run()
3344 	{
3345 		/*
3346 		 Errors
3347 		 An INVALID_VALUE error is generated if attribindex is greater than or
3348 		 equal to the value of MAX_VERTEX_ATTRIBS.
3349 		 An INVALID_VALUE error is generated if bindingindex is greater than or
3350 		 equal to the value of MAX_VERTEX_ATTRIB_BINDINGS.
3351 		 An INVALID_OPERATION error is generated if no vertex array object is
3352 		 bound.
3353 		 */
3354 		glBindVertexArray(m_vao);
3355 		GLint p;
3356 		glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &p);
3357 		glVertexAttribBinding(p + 1, 0);
3358 		if (glGetError() != GL_INVALID_VALUE)
3359 		{
3360 			m_context.getTestContext().getLog()
3361 				<< tcu::TestLog::Message
3362 				<< "INVALID_VALUE should be generated (attribindex greater than GL_MAX_VERTEX_ATTRIBS)."
3363 				<< tcu::TestLog::EndMessage;
3364 			return ERROR;
3365 		}
3366 		glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &p);
3367 		glVertexAttribBinding(0, p + 1);
3368 		if (glGetError() != GL_INVALID_VALUE)
3369 		{
3370 			m_context.getTestContext().getLog()
3371 				<< tcu::TestLog::Message
3372 				<< "INVALID_VALUE should be generated (bindingIndex greater than GL_MAX_VERTEX_ATTRIB_BINDINGS)."
3373 				<< tcu::TestLog::EndMessage;
3374 			return ERROR;
3375 		}
3376 		glBindVertexArray(0);
3377 		glVertexAttribBinding(0, 0);
3378 		if (glGetError() != GL_INVALID_OPERATION)
3379 		{
3380 			m_context.getTestContext().getLog()
3381 				<< tcu::TestLog::Message << "INVALID_OPERATION should be generated (default VAO)."
3382 				<< tcu::TestLog::EndMessage;
3383 			return ERROR;
3384 		}
3385 		return NO_ERROR;
3386 	}
3387 };
3388 //=============================================================================
3389 // 4.4 NegativeVertexAttribDivisor
3390 //-----------------------------------------------------------------------------
3391 class NegativeVertexAttribDivisor : public VertexAttribBindingBase
3392 {
3393 
3394 	GLuint m_vao;
3395 
Setup()3396 	virtual long Setup()
3397 	{
3398 		glGenVertexArrays(1, &m_vao);
3399 		return NO_ERROR;
3400 	}
3401 
Cleanup()3402 	virtual long Cleanup()
3403 	{
3404 		glDeleteVertexArrays(1, &m_vao);
3405 		return NO_ERROR;
3406 	}
3407 
Run()3408 	virtual long Run()
3409 	{
3410 		/*
3411 		 Errors
3412 		 An INVALID_VALUE error is generated if index is greater than or equal to
3413 		 the value of MAX_VERTEX_ATTRIBS.
3414 		 An INVALID_OPERATION error is generated if no vertex array object is
3415 		 bound.
3416 		 */
3417 		glBindVertexArray(m_vao);
3418 		GLint p;
3419 		glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &p);
3420 		glVertexBindingDivisor(p + 1, 1);
3421 		if (glGetError() != GL_INVALID_VALUE)
3422 		{
3423 			m_context.getTestContext().getLog()
3424 				<< tcu::TestLog::Message
3425 				<< "INVALID_VALUE should be generated (bindingIndex greater than GL_MAX_VERTEX_ATTRIBS)."
3426 				<< tcu::TestLog::EndMessage;
3427 			return ERROR;
3428 		}
3429 		glBindVertexArray(0);
3430 		glVertexBindingDivisor(0, 1);
3431 		if (glGetError() != GL_INVALID_OPERATION)
3432 		{
3433 			m_context.getTestContext().getLog()
3434 				<< tcu::TestLog::Message << "INVALID_OPERATION should be generated (default VAO)."
3435 				<< tcu::TestLog::EndMessage;
3436 			return ERROR;
3437 		}
3438 		return NO_ERROR;
3439 	}
3440 };
3441 //=============================================================================
3442 
3443 } // namespace
VertexAttribBindingTests(glcts::Context & context)3444 VertexAttribBindingTests::VertexAttribBindingTests(glcts::Context& context)
3445 	: TestCaseGroup(context, "vertex_attrib_binding", "")
3446 {
3447 }
3448 
~VertexAttribBindingTests(void)3449 VertexAttribBindingTests::~VertexAttribBindingTests(void)
3450 {
3451 }
3452 
init()3453 void VertexAttribBindingTests::init()
3454 {
3455 	using namespace glcts;
3456 	addChild(new TestSubcase(m_context, "basic-usage", TestSubcase::Create<BasicUsage>));
3457 	addChild(new TestSubcase(m_context, "basic-input-case1", TestSubcase::Create<BasicInputCase1>));
3458 	addChild(new TestSubcase(m_context, "basic-input-case2", TestSubcase::Create<BasicInputCase2>));
3459 	addChild(new TestSubcase(m_context, "basic-input-case3", TestSubcase::Create<BasicInputCase3>));
3460 	addChild(new TestSubcase(m_context, "basic-input-case4", TestSubcase::Create<BasicInputCase4>));
3461 	addChild(new TestSubcase(m_context, "basic-input-case5", TestSubcase::Create<BasicInputCase5>));
3462 	addChild(new TestSubcase(m_context, "basic-input-case6", TestSubcase::Create<BasicInputCase6>));
3463 	addChild(new TestSubcase(m_context, "basic-input-case8", TestSubcase::Create<BasicInputCase8>));
3464 	addChild(new TestSubcase(m_context, "basic-input-case9", TestSubcase::Create<BasicInputCase9>));
3465 	addChild(new TestSubcase(m_context, "basic-input-case11", TestSubcase::Create<BasicInputCase11>));
3466 	addChild(new TestSubcase(m_context, "basic-input-case12", TestSubcase::Create<BasicInputCase12>));
3467 	addChild(new TestSubcase(m_context, "basic-inputI-case1", TestSubcase::Create<BasicInputICase1>));
3468 	addChild(new TestSubcase(m_context, "basic-inputI-case2", TestSubcase::Create<BasicInputICase2>));
3469 	addChild(new TestSubcase(m_context, "basic-inputI-case3", TestSubcase::Create<BasicInputICase3>));
3470 	addChild(new TestSubcase(m_context, "basic-state1", TestSubcase::Create<BasicState1>));
3471 	addChild(new TestSubcase(m_context, "basic-state2", TestSubcase::Create<BasicState2>));
3472 	addChild(new TestSubcase(m_context, "advanced-bindingUpdate", TestSubcase::Create<AdvancedBindingUpdate>));
3473 	addChild(new TestSubcase(m_context, "advanced-iterations", TestSubcase::Create<AdvancedIterations>));
3474 	addChild(new TestSubcase(m_context, "advanced-largeStrideAndOffsetsNewAndLegacyAPI",
3475 							 TestSubcase::Create<AdvancedLargeStrideAndOffsetsNewAndLegacyAPI>));
3476 	addChild(new TestSubcase(m_context, "negative-bindVertexBuffer", TestSubcase::Create<NegativeBindVertexBuffer>));
3477 	addChild(
3478 		new TestSubcase(m_context, "negative-vertexAttribFormat", TestSubcase::Create<NegativeVertexAttribFormat>));
3479 	addChild(
3480 		new TestSubcase(m_context, "negative-vertexAttribBinding", TestSubcase::Create<NegativeVertexAttribBinding>));
3481 	addChild(
3482 		new TestSubcase(m_context, "negative-vertexAttribDivisor", TestSubcase::Create<NegativeVertexAttribDivisor>));
3483 }
3484 }
3485