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