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