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