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