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