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