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::Vec4;
37 using tcu::IVec4;
38 using tcu::UVec4;
39 using tcu::DVec4;
40 using tcu::Vec3;
41 using tcu::IVec3;
42 using tcu::DVec3;
43 using tcu::Vec2;
44 using tcu::IVec2;
45 using tcu::UVec2;
46 using tcu::Mat4;
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] = { "StageData.attrib[0]", "StageData.attrib[1]", "StageData.attrib[2]",
417 "StageData.attrib[3]", "StageData.attrib[4]", "StageData.attrib[5]",
418 "StageData.attrib[6]", "StageData.attrib[7]", "StageData.attrib[8]",
419 "StageData.attrib[9]", "StageData.attrib[10]", "StageData.attrib[11]",
420 "StageData.attrib[12]", "StageData.attrib[13]", "StageData.attrib[14]",
421 "StageData.attrib[15]" };
422 glTransformFeedbackVaryings(m_po, 16, v, GL_INTERLEAVED_ATTRIBS);
423 }
424 glLinkProgram(m_po);
425 if (!CheckProgram(m_po))
426 return ERROR;
427
428 {
429 std::vector<GLubyte> zero(sizeof(expected_data));
430 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_xfbo);
431 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(expected_data), &zero[0], GL_DYNAMIC_DRAW);
432 }
433
434 glEnable(GL_RASTERIZER_DISCARD);
435 glUseProgram(m_po);
436 glBeginTransformFeedback(GL_POINTS);
437 if (base_instance != -1)
438 {
439 glDrawArraysInstancedBaseInstance(GL_POINTS, 0, 2, instance_count, static_cast<GLuint>(base_instance));
440 }
441 else
442 {
443 glDrawArraysInstanced(GL_POINTS, 0, 2, instance_count);
444 }
445 glEndTransformFeedback();
446
447 Vec4 data[64];
448 glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(Vec4) * 64, &data[0]);
449
450 long status = NO_ERROR;
451 for (int i = 0; i < 64; ++i)
452 {
453 if (!ColorEqual(expected_data[i], data[i], Vec4(0.01f)))
454 {
455 m_context.getTestContext().getLog()
456 << tcu::TestLog::Message << "Data is: " << data[i][0] << " " << data[i][1] << " " << data[i][2]
457 << " " << data[i][3] << ", data should be: " << expected_data[i][0] << " " << expected_data[i][1]
458 << " " << expected_data[i][2] << " " << expected_data[i][3] << ", index is: " << i
459 << tcu::TestLog::EndMessage;
460 status = ERROR;
461 break;
462 }
463 }
464 return status;
465 }
466 };
467
468 //=============================================================================
469 // 1.2.1 BasicInputCase1
470 //-----------------------------------------------------------------------------
471 class BasicInputCase1 : public BasicInputBase
472 {
473 GLuint m_vao, m_vbo;
474
Setup()475 virtual long Setup()
476 {
477 BasicInputBase::Setup();
478 glGenVertexArrays(1, &m_vao);
479 glGenBuffers(1, &m_vbo);
480 return NO_ERROR;
481 }
482
Cleanup()483 virtual long Cleanup()
484 {
485 BasicInputBase::Cleanup();
486 glDeleteVertexArrays(1, &m_vao);
487 glDeleteBuffers(1, &m_vbo);
488 return NO_ERROR;
489 }
490
Run()491 virtual long Run()
492 {
493 for (GLuint i = 0; i < 16; ++i)
494 {
495 glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
496 }
497 glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
498 glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 2, NULL, GL_STATIC_DRAW);
499 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);
500 glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);
501 glBindBuffer(GL_ARRAY_BUFFER, 0);
502
503 glBindVertexArray(m_vao);
504 glBindVertexBuffer(0, m_vbo, 0, 12);
505 glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
506 glVertexAttribBinding(1, 0);
507 glEnableVertexAttribArray(1);
508
509 expected_data[1] = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
510 expected_data[17] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
511 return BasicInputBase::Run();
512 }
513 };
514
515 //=============================================================================
516 // 1.2.2 BasicInputCase2
517 //-----------------------------------------------------------------------------
518 class BasicInputCase2 : public BasicInputBase
519 {
520 GLuint m_vao, m_vbo;
521
Setup()522 virtual long Setup()
523 {
524 BasicInputBase::Setup();
525 glGenVertexArrays(1, &m_vao);
526 glGenBuffers(1, &m_vbo);
527 return NO_ERROR;
528 }
529
Cleanup()530 virtual long Cleanup()
531 {
532 BasicInputBase::Cleanup();
533 glDeleteVertexArrays(1, &m_vao);
534 glDeleteBuffers(1, &m_vbo);
535 return NO_ERROR;
536 }
537
Run()538 virtual long Run()
539 {
540 for (GLuint i = 0; i < 16; ++i)
541 {
542 glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
543 }
544 glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
545 glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 2, NULL, GL_STATIC_DRAW);
546 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);
547 glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);
548 glBindBuffer(GL_ARRAY_BUFFER, 0);
549
550 glBindVertexArray(m_vao);
551 glVertexAttribBinding(1, 0);
552 glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
553 glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
554 glVertexAttribFormat(7, 1, GL_FLOAT, GL_FALSE, 8);
555 glVertexAttribFormat(15, 2, GL_FLOAT, GL_FALSE, 4);
556 glVertexAttribBinding(0, 0);
557 glVertexAttribBinding(7, 0);
558 glVertexAttribBinding(15, 0);
559 glBindVertexBuffer(0, m_vbo, 0, 12);
560 glEnableVertexAttribArray(0);
561 glEnableVertexAttribArray(1);
562 glEnableVertexAttribArray(7);
563 glEnableVertexAttribArray(15);
564
565 expected_data[0] = Vec4(1.0f, 2.0f, 0.0f, 1.0f);
566 expected_data[1] = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
567 expected_data[7] = Vec4(3.0f, 0.0f, 0.0f, 1.0f);
568 expected_data[15] = Vec4(2.0f, 3.0f, 0.0f, 1.0f);
569 expected_data[16] = Vec4(4.0f, 5.0f, 0.0f, 1.0f);
570 expected_data[17] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
571 expected_data[23] = Vec4(6.0f, 0.0f, 0.0f, 1.0f);
572 expected_data[31] = Vec4(5.0f, 6.0f, 0.0f, 1.0f);
573 return BasicInputBase::Run();
574 }
575 };
576
577 //=============================================================================
578 // 1.2.3 BasicInputCase3
579 //-----------------------------------------------------------------------------
580 class BasicInputCase3 : public BasicInputBase
581 {
582 GLuint m_vao, m_vbo;
583
Setup()584 virtual long Setup()
585 {
586 BasicInputBase::Setup();
587 glGenVertexArrays(1, &m_vao);
588 glGenBuffers(1, &m_vbo);
589 return NO_ERROR;
590 }
591
Cleanup()592 virtual long Cleanup()
593 {
594 BasicInputBase::Cleanup();
595 glDeleteVertexArrays(1, &m_vao);
596 glDeleteBuffers(1, &m_vbo);
597 return NO_ERROR;
598 }
599
Run()600 virtual long Run()
601 {
602 for (GLuint i = 0; i < 16; ++i)
603 {
604 glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
605 }
606 glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
607 glBufferData(GL_ARRAY_BUFFER, 36 * 2, NULL, GL_STATIC_DRAW);
608 {
609 GLubyte d[] = { 1, 2, 3, 4 };
610 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
611 }
612 glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec3), &Vec3(5.0f, 6.0f, 7.0f)[0]);
613 glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(Vec2), &Vec2(8.0f, 9.0f)[0]);
614 {
615 GLubyte d[] = { 10, 11, 12, 13 };
616 glBufferSubData(GL_ARRAY_BUFFER, 0 + 36, sizeof(d), d);
617 }
618 glBufferSubData(GL_ARRAY_BUFFER, 16 + 36, sizeof(Vec3), &Vec3(14.0f, 15.0f, 16.0f)[0]);
619 glBufferSubData(GL_ARRAY_BUFFER, 28 + 36, sizeof(Vec2), &Vec2(17.0f, 18.0f)[0]);
620 glBindBuffer(GL_ARRAY_BUFFER, 0);
621
622 glBindVertexArray(m_vao);
623 glEnableVertexAttribArray(1);
624 glVertexAttribFormat(0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0);
625 glVertexAttribBinding(1, 3);
626 glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 16);
627 glVertexAttribBinding(2, 3);
628 glVertexAttribFormat(2, 2, GL_FLOAT, GL_FALSE, 28);
629 glVertexAttribBinding(0, 3);
630 glBindVertexBuffer(3, m_vbo, 0, 36);
631 glEnableVertexAttribArray(0);
632 glEnableVertexAttribArray(2);
633
634 expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
635 expected_data[1] = Vec4(5.0f, 6.0f, 7.0f, 1.0f);
636 expected_data[2] = Vec4(8.0f, 9.0f, 0.0f, 1.0f);
637 expected_data[0 + 16] = Vec4(10.0f, 11.0f, 12.0f, 13.0f);
638 expected_data[1 + 16] = Vec4(14.0f, 15.0f, 16.0f, 1.0f);
639 expected_data[2 + 16] = Vec4(17.0f, 18.0f, 0.0f, 1.0f);
640 return BasicInputBase::Run();
641 }
642 };
643
644 //=============================================================================
645 // 1.2.4 BasicInputCase4
646 //-----------------------------------------------------------------------------
647 class BasicInputCase4 : public BasicInputBase
648 {
649 GLuint m_vao, m_vbo[2];
650
Setup()651 virtual long Setup()
652 {
653 BasicInputBase::Setup();
654 glGenVertexArrays(1, &m_vao);
655 glGenBuffers(2, m_vbo);
656 return NO_ERROR;
657 }
658
Cleanup()659 virtual long Cleanup()
660 {
661 BasicInputBase::Cleanup();
662 glDeleteVertexArrays(1, &m_vao);
663 glDeleteBuffers(2, m_vbo);
664 return NO_ERROR;
665 }
666
Run()667 virtual long Run()
668 {
669 for (GLuint i = 0; i < 16; ++i)
670 {
671 glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
672 }
673 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
674 glBufferData(GL_ARRAY_BUFFER, 20 * 2, NULL, GL_STATIC_DRAW);
675 {
676 GLbyte d[] = { -127, 127, -127, 127 };
677 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
678 }
679 {
680 GLushort d[] = { 1, 2, 3, 4 };
681 glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);
682 }
683 {
684 GLuint d[] = { 5, 6 };
685 glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);
686 }
687 {
688 GLbyte d[] = { 127, -127, 127, -127 };
689 glBufferSubData(GL_ARRAY_BUFFER, 0 + 20, sizeof(d), d);
690 }
691 {
692 GLushort d[] = { 7, 8, 9, 10 };
693 glBufferSubData(GL_ARRAY_BUFFER, 4 + 20, sizeof(d), d);
694 }
695 {
696 GLuint d[] = { 11, 12 };
697 glBufferSubData(GL_ARRAY_BUFFER, 12 + 20, sizeof(d), d);
698 }
699 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
700 glBufferData(GL_ARRAY_BUFFER, 24 * 2 + 8, NULL, GL_STATIC_DRAW);
701 {
702 GLdouble d[] = { 0.0, 100.0, 200.0 };
703 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
704 }
705 {
706 GLdouble d[] = { 300.0, 400.0 };
707 glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);
708 }
709 glBindBuffer(GL_ARRAY_BUFFER, 0);
710
711 glBindVertexArray(m_vao);
712 glVertexAttribFormat(0, 4, GL_BYTE, GL_TRUE, 0);
713 glVertexAttribFormat(1, 4, GL_UNSIGNED_SHORT, GL_FALSE, 4);
714 glVertexAttribFormat(2, 2, GL_UNSIGNED_INT, GL_FALSE, 12);
715 glVertexAttribFormat(5, 2, GL_DOUBLE, GL_FALSE, 0);
716 glVertexAttribBinding(0, 0);
717 glVertexAttribBinding(1, 0);
718 glVertexAttribBinding(2, 0);
719 glVertexAttribBinding(5, 6);
720 glBindVertexBuffer(0, m_vbo[0], 0, 20);
721 glBindVertexBuffer(6, m_vbo[1], 8, 24);
722 glEnableVertexAttribArray(0);
723 glEnableVertexAttribArray(1);
724 glEnableVertexAttribArray(2);
725 glEnableVertexAttribArray(5);
726
727 expected_data[0] = Vec4(-1.0f, 1.0f, -1.0f, 1.0f);
728 expected_data[1] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
729 expected_data[2] = Vec4(5.0f, 6.0f, 0.0f, 1.0f);
730 expected_data[5] = Vec4(100.0f, 200.0f, 0.0f, 1.0f);
731 expected_data[0 + 16] = Vec4(1.0f, -1.0f, 1.0f, -1.0f);
732 expected_data[1 + 16] = Vec4(7.0f, 8.0f, 9.0f, 10.0f);
733 expected_data[2 + 16] = Vec4(11.0f, 12.0f, 0.0f, 1.0f);
734 expected_data[5 + 16] = Vec4(300.0f, 400.0f, 0.0f, 1.0f);
735 return BasicInputBase::Run();
736 }
737 };
738
739 //=============================================================================
740 // 1.2.5 BasicInputCase5
741 //-----------------------------------------------------------------------------
742 class BasicInputCase5 : public BasicInputBase
743 {
744 GLuint m_vao, m_vbo;
745
Setup()746 virtual long Setup()
747 {
748 BasicInputBase::Setup();
749 glGenVertexArrays(1, &m_vao);
750 glGenBuffers(1, &m_vbo);
751 return NO_ERROR;
752 }
753
Cleanup()754 virtual long Cleanup()
755 {
756 BasicInputBase::Cleanup();
757 glDeleteVertexArrays(1, &m_vao);
758 glDeleteBuffers(1, &m_vbo);
759 return NO_ERROR;
760 }
761
Run()762 virtual long Run()
763 {
764 for (GLuint i = 0; i < 16; ++i)
765 {
766 glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
767 }
768 const int kStride = 116;
769 glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
770 glBufferData(GL_ARRAY_BUFFER, kStride * 2, NULL, GL_STATIC_DRAW);
771 {
772 GLubyte d[] = { 0, 0xff, 0xff / 2, 0 };
773 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
774 }
775 {
776 GLushort d[] = { 0, 0xffff, 0xffff / 2, 0 };
777 glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);
778 }
779 {
780 GLuint d[] = { 0, 0xffffffff, 0xffffffff / 2, 0 };
781 glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);
782 }
783 {
784 GLbyte d[] = { 0, -127, 127, 0 };
785 glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(d), d);
786 }
787 {
788 GLshort d[] = { 0, -32767, 32767, 0 };
789 glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);
790 }
791 {
792 GLint d[] = { 0, -2147483647, 2147483647, 0 };
793 glBufferSubData(GL_ARRAY_BUFFER, 40, sizeof(d), d);
794 }
795 {
796 GLfloat d[] = { 0, 1.0f, 2.0f, 0 };
797 glBufferSubData(GL_ARRAY_BUFFER, 56, sizeof(d), d);
798 }
799 {
800 GLdouble d[] = { 0, 10.0, 20.0, 0 };
801 glBufferSubData(GL_ARRAY_BUFFER, 72, sizeof(d), d);
802 }
803 {
804 GLubyte d[] = { 0, 0xff / 4, 0xff / 2, 0xff };
805 glBufferSubData(GL_ARRAY_BUFFER, 104, sizeof(d), d);
806 }
807 {
808 GLuint d = 0 | (1023 << 10) | (511 << 20) | (1 << 30);
809 glBufferSubData(GL_ARRAY_BUFFER, 108, sizeof(d), &d);
810 }
811 {
812 GLint d = 0 | (511 << 10) | (255 << 20) | (0 << 30);
813 glBufferSubData(GL_ARRAY_BUFFER, 112, sizeof(d), &d);
814 }
815
816 {
817 GLubyte d[] = { 0xff, 0xff, 0xff / 2, 0 };
818 glBufferSubData(GL_ARRAY_BUFFER, 0 + kStride, sizeof(d), d);
819 }
820 {
821 GLushort d[] = { 0xffff, 0xffff, 0xffff / 2, 0 };
822 glBufferSubData(GL_ARRAY_BUFFER, 4 + kStride, sizeof(d), d);
823 }
824 {
825 GLuint d[] = { 0xffffffff, 0xffffffff, 0xffffffff / 2, 0 };
826 glBufferSubData(GL_ARRAY_BUFFER, 12 + kStride, sizeof(d), d);
827 }
828 {
829 GLbyte d[] = { 127, -127, 127, 0 };
830 glBufferSubData(GL_ARRAY_BUFFER, 28 + kStride, sizeof(d), d);
831 }
832 {
833 GLshort d[] = { 32767, -32767, 32767, 0 };
834 glBufferSubData(GL_ARRAY_BUFFER, 32 + kStride, sizeof(d), d);
835 }
836 {
837 GLint d[] = { 2147483647, -2147483647, 2147483647, 0 };
838 glBufferSubData(GL_ARRAY_BUFFER, 40 + kStride, sizeof(d), d);
839 }
840 {
841 GLfloat d[] = { 0, 3.0f, 4.0f, 0 };
842 glBufferSubData(GL_ARRAY_BUFFER, 56 + kStride, sizeof(d), d);
843 }
844 {
845 GLdouble d[] = { 0, 30.0, 40.0, 0 };
846 glBufferSubData(GL_ARRAY_BUFFER, 72 + kStride, sizeof(d), d);
847 }
848 {
849 GLubyte d[] = { 0xff, 0xff / 2, 0xff / 4, 0 };
850 glBufferSubData(GL_ARRAY_BUFFER, 104 + kStride, sizeof(d), d);
851 }
852 {
853 GLuint d = 0 | (1023 << 10) | (511 << 20) | (2u << 30);
854 glBufferSubData(GL_ARRAY_BUFFER, 108 + kStride, sizeof(d), &d);
855 }
856 {
857 GLint d = (-511 & 0x3ff) | (511 << 10) | (255 << 20) | 3 << 30;
858 glBufferSubData(GL_ARRAY_BUFFER, 112 + kStride, sizeof(d), &d);
859 }
860 glBindBuffer(GL_ARRAY_BUFFER, 0);
861
862 glBindVertexArray(m_vao);
863 glVertexAttribFormat(0, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0);
864 glVertexAttribFormat(1, 4, GL_UNSIGNED_SHORT, GL_TRUE, 4);
865 glVertexAttribFormat(2, 4, GL_UNSIGNED_INT, GL_TRUE, 12);
866 glVertexAttribFormat(3, 4, GL_BYTE, GL_TRUE, 28);
867 glVertexAttribFormat(4, 4, GL_SHORT, GL_TRUE, 32);
868 glVertexAttribFormat(5, 4, GL_INT, GL_TRUE, 40);
869 glVertexAttribFormat(6, 4, GL_FLOAT, GL_TRUE, 56);
870 glVertexAttribFormat(7, 4, GL_DOUBLE, GL_TRUE, 72);
871 glVertexAttribFormat(8, GL_BGRA, GL_UNSIGNED_BYTE, GL_TRUE, 104);
872 glVertexAttribFormat(9, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 108);
873 glVertexAttribFormat(10, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, GL_TRUE, 108);
874 glVertexAttribFormat(11, 4, GL_INT_2_10_10_10_REV, GL_TRUE, 112);
875 glVertexAttribFormat(12, GL_BGRA, GL_INT_2_10_10_10_REV, GL_TRUE, 112);
876
877 for (GLuint i = 0; i < 13; ++i)
878 {
879 glVertexAttribBinding(i, 0);
880 glEnableVertexAttribArray(i);
881 }
882 glBindVertexBuffer(0, m_vbo, 0, kStride);
883
884 expected_data[0] = Vec4(0.0f, 1.0f, 0.5f, 0.0f);
885 expected_data[1] = Vec4(0.0f, 1.0f, 0.5f, 0.0f);
886 expected_data[2] = Vec4(0.0f, 1.0f, 0.5f, 0.0f);
887 expected_data[3] = Vec4(0.0f, -1.0f, 1.0f, 0.0f);
888 expected_data[4] = Vec4(0.0f, -1.0f, 1.0f, 0.0f);
889 expected_data[5] = Vec4(0.0f, -1.0f, 1.0f, 0.0f);
890 expected_data[6] = Vec4(0.0f, 1.0f, 2.0f, 0.0f);
891 expected_data[7] = Vec4(0.0f, 10.0f, 20.0f, 0.0f);
892 expected_data[8] = Vec4(0.5f, 0.25f, 0.0f, 1.0f);
893 expected_data[9] = Vec4(0.0f, 1.0f, 0.5f, 0.33f);
894 expected_data[10] = Vec4(0.5f, 1.0f, 0.0f, 0.33f);
895 expected_data[11] = Vec4(0.0f, 1.0f, 0.5f, 0.0f);
896 expected_data[12] = Vec4(0.5f, 1.0f, 0.0f, 0.0f);
897 expected_data[0 + 16] = Vec4(1.0f, 1.0f, 0.5f, 0.0f);
898 expected_data[1 + 16] = Vec4(1.0f, 1.0f, 0.5f, 0.0f);
899 expected_data[2 + 16] = Vec4(1.0f, 1.0f, 0.5f, 0.0f);
900 expected_data[3 + 16] = Vec4(1.0f, -1.0f, 1.0f, 0.0f);
901 expected_data[4 + 16] = Vec4(1.0f, -1.0f, 1.0f, 0.0f);
902 expected_data[5 + 16] = Vec4(1.0f, -1.0f, 1.0f, 0.0f);
903 expected_data[6 + 16] = Vec4(0.0f, 3.0f, 4.0f, 0.0f);
904 expected_data[7 + 16] = Vec4(0.0f, 30.0f, 40.0f, 0.0f);
905 expected_data[8 + 16] = Vec4(0.25f, 0.5f, 1.0f, 0.0f);
906 expected_data[9 + 16] = Vec4(0.0f, 1.0f, 0.5f, 0.66f);
907 expected_data[10 + 16] = Vec4(0.5f, 1.0f, 0.0f, 0.66f);
908 expected_data[11 + 16] = Vec4(-1.0f, 1.0f, 0.5f, -1.0f);
909 expected_data[12 + 16] = Vec4(0.5f, 1.0f, -1.0f, -1.0f);
910 return BasicInputBase::Run();
911 }
912 };
913
914 //=============================================================================
915 // 1.2.6 BasicInputCase6
916 //-----------------------------------------------------------------------------
917 class BasicInputCase6 : public BasicInputBase
918 {
919 GLuint m_vao, m_vbo;
920
Setup()921 virtual long Setup()
922 {
923 BasicInputBase::Setup();
924 glGenVertexArrays(1, &m_vao);
925 glGenBuffers(1, &m_vbo);
926 return NO_ERROR;
927 }
928
Cleanup()929 virtual long Cleanup()
930 {
931 BasicInputBase::Cleanup();
932 glDeleteVertexArrays(1, &m_vao);
933 glDeleteBuffers(1, &m_vbo);
934 return NO_ERROR;
935 }
936
Run()937 virtual long Run()
938 {
939 for (GLuint i = 0; i < 16; ++i)
940 {
941 glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
942 }
943 const int kStride = 112;
944 glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
945 glBufferData(GL_ARRAY_BUFFER, kStride * 2, NULL, GL_STATIC_DRAW);
946 {
947 GLubyte d[] = { 1, 2, 3, 4 };
948 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
949 }
950 {
951 GLushort d[] = { 5, 6, 7, 8 };
952 glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);
953 }
954 {
955 GLuint d[] = { 9, 10, 11, 12 };
956 glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);
957 }
958 {
959 GLbyte d[] = { -1, 2, -3, 4 };
960 glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(d), d);
961 }
962 {
963 GLshort d[] = { -5, 6, -7, 8 };
964 glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);
965 }
966 {
967 GLint d[] = { -9, 10, -11, 12 };
968 glBufferSubData(GL_ARRAY_BUFFER, 40, sizeof(d), d);
969 }
970 {
971 GLfloat d[] = { -13.0f, 14.0f, -15.0f, 16.0f };
972 glBufferSubData(GL_ARRAY_BUFFER, 56, sizeof(d), d);
973 }
974 {
975 GLdouble d[] = { -18.0, 19.0, -20.0, 21.0 };
976 glBufferSubData(GL_ARRAY_BUFFER, 72, sizeof(d), d);
977 }
978 {
979 GLuint d = 0 | (11 << 10) | (12 << 20) | (2u << 30);
980 glBufferSubData(GL_ARRAY_BUFFER, 104, sizeof(d), &d);
981 }
982 {
983 GLint d = 0 | ((0xFFFFFFF5 << 10) & (0x3ff << 10)) | (12 << 20) | (1 << 30);
984 glBufferSubData(GL_ARRAY_BUFFER, 108, sizeof(d), &d);
985 }
986 {
987 GLubyte d[] = { 22, 23, 24, 25 };
988 glBufferSubData(GL_ARRAY_BUFFER, 0 + kStride, sizeof(d), d);
989 }
990 {
991 GLushort d[] = { 26, 27, 28, 29 };
992 glBufferSubData(GL_ARRAY_BUFFER, 4 + kStride, sizeof(d), d);
993 }
994 {
995 GLuint d[] = { 30, 31, 32, 33 };
996 glBufferSubData(GL_ARRAY_BUFFER, 12 + kStride, sizeof(d), d);
997 }
998 {
999 GLbyte d[] = { -34, 35, -36, 37 };
1000 glBufferSubData(GL_ARRAY_BUFFER, 28 + kStride, sizeof(d), d);
1001 }
1002 {
1003 GLshort d[] = { -38, 39, -40, 41 };
1004 glBufferSubData(GL_ARRAY_BUFFER, 32 + kStride, sizeof(d), d);
1005 }
1006 {
1007 GLint d[] = { -42, 43, -44, 45 };
1008 glBufferSubData(GL_ARRAY_BUFFER, 40 + kStride, sizeof(d), d);
1009 }
1010 {
1011 GLfloat d[] = { -46.0f, 47.0f, -48.0f, 49.0f };
1012 glBufferSubData(GL_ARRAY_BUFFER, 56 + kStride, sizeof(d), d);
1013 }
1014 {
1015 GLdouble d[] = { -50.0, 51.0, -52.0, 53.0 };
1016 glBufferSubData(GL_ARRAY_BUFFER, 72 + kStride, sizeof(d), d);
1017 }
1018 {
1019 GLuint d = 0 | (11 << 10) | (12 << 20) | (1 << 30);
1020 glBufferSubData(GL_ARRAY_BUFFER, 104 + kStride, sizeof(d), &d);
1021 }
1022 {
1023 GLint d = 123 | ((0xFFFFFFFD << 10) & (0x3ff << 10)) | ((0xFFFFFE0C << 20) & (0x3ff << 20)) |
1024 ((0xFFFFFFFF << 30) & (0x3 << 30));
1025 glBufferSubData(GL_ARRAY_BUFFER, 108 + kStride, sizeof(d), &d);
1026 }
1027 glBindBuffer(GL_ARRAY_BUFFER, 0);
1028
1029 glBindVertexArray(m_vao);
1030 glVertexAttribFormat(0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0);
1031 glVertexAttribFormat(1, 4, GL_UNSIGNED_SHORT, GL_FALSE, 4);
1032 glVertexAttribFormat(2, 4, GL_UNSIGNED_INT, GL_FALSE, 12);
1033 glVertexAttribFormat(3, 4, GL_BYTE, GL_FALSE, 28);
1034 glVertexAttribFormat(4, 4, GL_SHORT, GL_FALSE, 32);
1035 glVertexAttribFormat(5, 4, GL_INT, GL_FALSE, 40);
1036 glVertexAttribFormat(6, 4, GL_FLOAT, GL_FALSE, 56);
1037 glVertexAttribFormat(7, 4, GL_DOUBLE, GL_FALSE, 72);
1038 glVertexAttribFormat(8, 4, GL_UNSIGNED_INT_2_10_10_10_REV, GL_FALSE, 104);
1039 glVertexAttribFormat(9, 4, GL_INT_2_10_10_10_REV, GL_FALSE, 108);
1040 for (GLuint i = 0; i < 10; ++i)
1041 {
1042 glVertexAttribBinding(i, 0);
1043 glEnableVertexAttribArray(i);
1044 }
1045 glBindVertexBuffer(0, m_vbo, 0, kStride);
1046
1047 expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1048 expected_data[1] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1049 expected_data[2] = Vec4(9.0f, 10.0f, 11.0f, 12.0f);
1050 expected_data[3] = Vec4(-1.0f, 2.0f, -3.0f, 4.0f);
1051 expected_data[4] = Vec4(-5.0f, 6.0f, -7.0f, 8.0f);
1052 expected_data[5] = Vec4(-9.0f, 10.0f, -11.0f, 12.0f);
1053 expected_data[6] = Vec4(-13.0f, 14.0f, -15.0f, 16.0f);
1054 expected_data[7] = Vec4(-18.0f, 19.0f, -20.0f, 21.0f);
1055 expected_data[8] = Vec4(0.0f, 11.0f, 12.0f, 2.0f);
1056 expected_data[9] = Vec4(0.0f, -11.0f, 12.0f, 1.0f);
1057 expected_data[0 + 16] = Vec4(22.0f, 23.0f, 24.0f, 25.0f);
1058 expected_data[1 + 16] = Vec4(26.0f, 27.0f, 28.0f, 29.0f);
1059 expected_data[2 + 16] = Vec4(30.0f, 31.0f, 32.0f, 33.0f);
1060 expected_data[3 + 16] = Vec4(-34.0f, 35.0f, -36.0f, 37.0f);
1061 expected_data[4 + 16] = Vec4(-38.0f, 39.0f, -40.0f, 41.0f);
1062 expected_data[5 + 16] = Vec4(-42.0f, 43.0f, -44.0f, 45.0f);
1063 expected_data[6 + 16] = Vec4(-46.0f, 47.0f, -48.0f, 49.0f);
1064 expected_data[7 + 16] = Vec4(-50.0f, 51.0f, -52.0f, 53.0f);
1065 expected_data[8 + 16] = Vec4(0.0f, 11.0f, 12.0f, 1.0f);
1066 expected_data[9 + 16] = Vec4(123.0f, -3.0f, -500.0f, -1.0f);
1067 return BasicInputBase::Run();
1068 }
1069 };
1070
1071 //=============================================================================
1072 // 1.2.7 BasicInputCase7
1073 //-----------------------------------------------------------------------------
1074 class BasicInputCase7 : public BasicInputBase
1075 {
1076 GLuint m_vao, m_vbo[2];
1077
Setup()1078 virtual long Setup()
1079 {
1080 BasicInputBase::Setup();
1081 glGenVertexArrays(1, &m_vao);
1082 glGenBuffers(2, m_vbo);
1083 return NO_ERROR;
1084 }
1085
Cleanup()1086 virtual long Cleanup()
1087 {
1088 BasicInputBase::Cleanup();
1089 glDeleteVertexArrays(1, &m_vao);
1090 glDeleteBuffers(2, m_vbo);
1091 return NO_ERROR;
1092 }
1093
Run()1094 virtual long Run()
1095 {
1096 for (GLuint i = 0; i < 16; ++i)
1097 {
1098 glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
1099 }
1100 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
1101 glBufferData(GL_ARRAY_BUFFER, 6 * 4, NULL, GL_STATIC_DRAW);
1102 {
1103 GLfloat d[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f };
1104 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
1105 }
1106
1107 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
1108 glBufferData(GL_ARRAY_BUFFER, 10 * 4, NULL, GL_STATIC_DRAW);
1109 {
1110 GLfloat d[] = { -1.0f, -2.0f, -3.0f, -4.0f, -5.0f, -6.0f, -7.0f, -8.0f, -9.0f, -10.0f };
1111 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
1112 }
1113 glBindBuffer(GL_ARRAY_BUFFER, 0);
1114
1115 glBindVertexArray(m_vao);
1116 glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
1117 glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
1118 glVertexAttribFormat(2, 1, GL_FLOAT, GL_FALSE, 4);
1119 glVertexAttribFormat(5, 4, GL_FLOAT, GL_FALSE, 12);
1120 glVertexAttribFormat(14, 2, GL_FLOAT, GL_FALSE, 8);
1121 glVertexAttribBinding(0, 0);
1122 glVertexAttribBinding(1, 1);
1123 glVertexAttribBinding(2, 1);
1124 glVertexAttribBinding(5, 15);
1125 glVertexAttribBinding(14, 7);
1126 glBindVertexBuffer(0, m_vbo[0], 0, 12);
1127 glBindVertexBuffer(1, m_vbo[0], 4, 4);
1128 glBindVertexBuffer(7, m_vbo[1], 8, 16);
1129 glBindVertexBuffer(15, m_vbo[1], 12, 0);
1130 glEnableVertexAttribArray(0);
1131 glEnableVertexAttribArray(1);
1132 glEnableVertexAttribArray(2);
1133 glEnableVertexAttribArray(5);
1134 glEnableVertexAttribArray(14);
1135
1136 base_instance = 0;
1137 expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
1138 expected_data[1] = Vec4(2.0f, 3.0f, 4.0f, 1.0f);
1139 expected_data[2] = Vec4(3.0f, 0.0f, 0.0f, 1.0f);
1140 expected_data[5] = Vec4(-7.0f, -8.0f, -9.0f, -10.0f);
1141 expected_data[14] = Vec4(-5.0f, -6.0f, 0.0f, 1.0f);
1142 expected_data[0 + 16] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
1143 expected_data[1 + 16] = Vec4(3.0f, 4.0f, 5.0f, 1.0f);
1144 expected_data[2 + 16] = Vec4(4.0f, 0.0f, 0.0f, 1.0f);
1145 expected_data[5 + 16] = Vec4(-7.0f, -8.0f, -9.0f, -10.0f);
1146 expected_data[14 + 16] = Vec4(-9.0f, -10.0f, 0.0f, 1.0f);
1147 return BasicInputBase::Run();
1148 }
1149 };
1150
1151 //=============================================================================
1152 // 1.2.8 BasicInputCase8
1153 //-----------------------------------------------------------------------------
1154 class BasicInputCase8 : public BasicInputBase
1155 {
1156 GLuint m_vao, m_vbo[2];
1157
Setup()1158 virtual long Setup()
1159 {
1160 BasicInputBase::Setup();
1161 glGenVertexArrays(1, &m_vao);
1162 glGenBuffers(2, m_vbo);
1163 return NO_ERROR;
1164 }
1165
Cleanup()1166 virtual long Cleanup()
1167 {
1168 BasicInputBase::Cleanup();
1169 glDeleteVertexArrays(1, &m_vao);
1170 glDeleteBuffers(2, m_vbo);
1171 return NO_ERROR;
1172 }
1173
Run()1174 virtual long Run()
1175 {
1176 for (GLuint i = 0; i < 16; ++i)
1177 {
1178 glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
1179 }
1180 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
1181 glBufferData(GL_ARRAY_BUFFER, 6 * 4, NULL, GL_STATIC_DRAW);
1182 {
1183 GLfloat d[] = { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f };
1184 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
1185 }
1186
1187 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
1188 glBufferData(GL_ARRAY_BUFFER, 10 * 4, NULL, GL_STATIC_DRAW);
1189 {
1190 GLfloat d[] = { -1.0f, -2.0f, -3.0f, -4.0f, -5.0f, -6.0f, -7.0f, -8.0f, -9.0f, -10.0f };
1191 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
1192 }
1193 glBindBuffer(GL_ARRAY_BUFFER, 0);
1194
1195 glBindVertexArray(m_vao);
1196 glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
1197 glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
1198 glVertexAttribFormat(2, 1, GL_FLOAT, GL_FALSE, 4);
1199 glVertexAttribFormat(5, 4, GL_FLOAT, GL_FALSE, 12);
1200 glVertexAttribFormat(14, 2, GL_FLOAT, GL_FALSE, 8);
1201 glVertexAttribBinding(0, 0);
1202 glVertexAttribBinding(1, 1);
1203 glVertexAttribBinding(2, 1);
1204 glVertexAttribBinding(5, 15);
1205 glVertexAttribBinding(14, 7);
1206 glBindVertexBuffer(0, m_vbo[0], 0, 12);
1207 glBindVertexBuffer(1, m_vbo[0], 4, 4);
1208 glBindVertexBuffer(7, m_vbo[1], 8, 16);
1209 glBindVertexBuffer(15, m_vbo[1], 12, 0);
1210 glEnableVertexAttribArray(0);
1211 glEnableVertexAttribArray(1);
1212 glEnableVertexAttribArray(2);
1213 glEnableVertexAttribArray(5);
1214 glEnableVertexAttribArray(14);
1215
1216 expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
1217 expected_data[1] = Vec4(2.0f, 3.0f, 4.0f, 1.0f);
1218 expected_data[2] = Vec4(3.0f, 0.0f, 0.0f, 1.0f);
1219 expected_data[5] = Vec4(-7.0f, -8.0f, -9.0f, -10.0f);
1220 expected_data[14] = Vec4(-5.0f, -6.0f, 0.0f, 1.0f);
1221 expected_data[0 + 16] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
1222 expected_data[1 + 16] = Vec4(3.0f, 4.0f, 5.0f, 1.0f);
1223 expected_data[2 + 16] = Vec4(4.0f, 0.0f, 0.0f, 1.0f);
1224 expected_data[5 + 16] = Vec4(-7.0f, -8.0f, -9.0f, -10.0f);
1225 expected_data[14 + 16] = Vec4(-9.0f, -10.0f, 0.0f, 1.0f);
1226 return BasicInputBase::Run();
1227 }
1228 };
1229
1230 //=============================================================================
1231 // 1.2.9 BasicInputCase9
1232 //-----------------------------------------------------------------------------
1233 class BasicInputCase9 : public BasicInputBase
1234 {
1235 GLuint m_vao, m_vbo[2];
1236
Setup()1237 virtual long Setup()
1238 {
1239 BasicInputBase::Setup();
1240 glGenVertexArrays(1, &m_vao);
1241 glGenBuffers(2, m_vbo);
1242 return NO_ERROR;
1243 }
1244
Cleanup()1245 virtual long Cleanup()
1246 {
1247 BasicInputBase::Cleanup();
1248 glDeleteVertexArrays(1, &m_vao);
1249 glDeleteBuffers(2, m_vbo);
1250 return NO_ERROR;
1251 }
1252
Run()1253 virtual long Run()
1254 {
1255 for (GLuint i = 0; i < 16; ++i)
1256 {
1257 glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
1258 }
1259 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
1260 glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);
1261 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(1.0f, 2.0f, 3.0f, 4.0f)[0]);
1262 glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(5.0f, 6.0f, 7.0f, 8.0f)[0]);
1263 glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(Vec4), &Vec4(9.0f, 10.0f, 11.0f, 12.0f)[0]);
1264 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
1265 glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);
1266 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(10.0f, 20.0f, 30.0f, 40.0f)[0]);
1267 glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(50.0f, 60.0f, 70.0f, 80.0f)[0]);
1268 glBindBuffer(GL_ARRAY_BUFFER, 0);
1269
1270 glBindVertexArray(m_vao);
1271 glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, 0);
1272 glVertexAttribFormat(2, 4, GL_FLOAT, GL_FALSE, 0);
1273 glVertexAttribFormat(4, 2, GL_FLOAT, GL_FALSE, 4);
1274 glVertexAttribBinding(0, 0);
1275 glVertexAttribBinding(2, 1);
1276 glVertexAttribBinding(4, 3);
1277 glEnableVertexAttribArray(0);
1278 glEnableVertexAttribArray(2);
1279 glEnableVertexAttribArray(4);
1280 glBindVertexBuffer(0, m_vbo[0], 0, 16);
1281 glBindVertexBuffer(1, m_vbo[0], 0, 16);
1282 glBindVertexBuffer(3, m_vbo[1], 4, 8);
1283 glVertexBindingDivisor(1, 1);
1284
1285 instance_count = 2;
1286 base_instance = 0;
1287 expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1288 expected_data[2] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1289 expected_data[4] = Vec4(30.0f, 40.0f, 0.0f, 1.0f);
1290 expected_data[0 + 16] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1291 expected_data[2 + 16] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1292 expected_data[4 + 16] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);
1293
1294 expected_data[0 + 32] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1295 expected_data[2 + 32] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1296 expected_data[4 + 32] = Vec4(30.0f, 40.0f, 0.0f, 1.0f);
1297 expected_data[0 + 16 + 32] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1298 expected_data[2 + 16 + 32] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1299 expected_data[4 + 16 + 32] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);
1300 return BasicInputBase::Run();
1301 }
1302 };
1303
1304 //=============================================================================
1305 // 1.2.10 BasicInputCase10
1306 //-----------------------------------------------------------------------------
1307 class BasicInputCase10 : public BasicInputBase
1308 {
1309 GLuint m_vao, m_vbo;
1310
Setup()1311 virtual long Setup()
1312 {
1313 BasicInputBase::Setup();
1314 glGenVertexArrays(1, &m_vao);
1315 glGenBuffers(1, &m_vbo);
1316 return NO_ERROR;
1317 }
1318
Cleanup()1319 virtual long Cleanup()
1320 {
1321 BasicInputBase::Cleanup();
1322 glDeleteVertexArrays(1, &m_vao);
1323 glDeleteBuffers(1, &m_vbo);
1324 return NO_ERROR;
1325 }
1326
Run()1327 virtual long Run()
1328 {
1329 for (GLuint i = 0; i < 16; ++i)
1330 {
1331 glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
1332 }
1333 glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1334 glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 3, NULL, GL_STATIC_DRAW);
1335 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);
1336 glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);
1337 glBufferSubData(GL_ARRAY_BUFFER, 24, sizeof(Vec3), &Vec3(7.0f, 8.0f, 9.0f)[0]);
1338 glBindBuffer(GL_ARRAY_BUFFER, 0);
1339
1340 glBindVertexArray(m_vao);
1341 glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
1342 glVertexAttribFormat(2, 2, GL_FLOAT, GL_FALSE, 4);
1343 glVertexAttribBinding(0, 0);
1344 glVertexAttribBinding(2, 3);
1345 glBindVertexBuffer(0, m_vbo, 0, 12);
1346 glBindVertexBuffer(3, m_vbo, 4, 8);
1347 glEnableVertexAttribArray(0);
1348 glEnableVertexAttribArray(2);
1349 glVertexBindingDivisor(0, 1);
1350 glVertexBindingDivisor(3, 0);
1351
1352 instance_count = 2;
1353 base_instance = 1;
1354 expected_data[0] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
1355 expected_data[2] = Vec4(3.0f, 4.0f, 0.0f, 1.0f);
1356 expected_data[0 + 16] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
1357 expected_data[2 + 16] = Vec4(5.0f, 6.0f, 0.0f, 1.0f);
1358
1359 expected_data[0 + 32] = Vec4(7.0f, 8.0f, 9.0f, 1.0f);
1360 expected_data[2 + 32] = Vec4(3.0f, 4.0f, 0.0f, 1.0f);
1361 expected_data[0 + 16 + 32] = Vec4(7.0f, 8.0f, 9.0f, 1.0f);
1362 expected_data[2 + 16 + 32] = Vec4(5.0f, 6.0f, 0.0f, 1.0f);
1363 return BasicInputBase::Run();
1364 }
1365 };
1366
1367 //=============================================================================
1368 // 1.2.11 BasicInputCase11
1369 //-----------------------------------------------------------------------------
1370 class BasicInputCase11 : public BasicInputBase
1371 {
1372 GLuint m_vao, m_vbo[2];
1373
Setup()1374 virtual long Setup()
1375 {
1376 BasicInputBase::Setup();
1377 glGenVertexArrays(1, &m_vao);
1378 glGenBuffers(2, m_vbo);
1379 return NO_ERROR;
1380 }
1381
Cleanup()1382 virtual long Cleanup()
1383 {
1384 BasicInputBase::Cleanup();
1385 glDeleteVertexArrays(1, &m_vao);
1386 glDeleteBuffers(2, m_vbo);
1387 return NO_ERROR;
1388 }
1389
Run()1390 virtual long Run()
1391 {
1392 for (GLuint i = 0; i < 16; ++i)
1393 {
1394 glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
1395 }
1396 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
1397 glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);
1398 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(1.0f, 2.0f, 3.0f, 4.0f)[0]);
1399 glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(5.0f, 6.0f, 7.0f, 8.0f)[0]);
1400 glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(Vec4), &Vec4(9.0f, 10.0f, 11.0f, 12.0f)[0]);
1401 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
1402 glBufferData(GL_ARRAY_BUFFER, sizeof(Vec4) * 3, NULL, GL_STATIC_DRAW);
1403 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec4), &Vec4(10.0f, 20.0f, 30.0f, 40.0f)[0]);
1404 glBufferSubData(GL_ARRAY_BUFFER, 16, sizeof(Vec4), &Vec4(50.0f, 60.0f, 70.0f, 80.0f)[0]);
1405 glBindBuffer(GL_ARRAY_BUFFER, 0);
1406
1407 glBindVertexArray(m_vao);
1408 glVertexAttribFormat(0, 4, GL_FLOAT, GL_FALSE, 0);
1409 glVertexAttribFormat(2, 4, GL_FLOAT, GL_FALSE, 0);
1410 glVertexAttribFormat(4, 2, GL_FLOAT, GL_FALSE, 4);
1411 glVertexAttribBinding(0, 0);
1412 glVertexAttribBinding(2, 1);
1413 glVertexAttribBinding(4, 2);
1414 glEnableVertexAttribArray(0);
1415 glEnableVertexAttribArray(2);
1416 glEnableVertexAttribArray(4);
1417 glBindVertexBuffer(0, m_vbo[0], 0, 16);
1418 glBindVertexBuffer(1, m_vbo[0], 0, 16);
1419 glBindVertexBuffer(2, m_vbo[1], 4, 8);
1420 glVertexBindingDivisor(1, 1);
1421
1422 instance_count = 2;
1423 expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1424 expected_data[2] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1425 expected_data[4] = Vec4(30.0f, 40.0f, 0.0f, 1.0f);
1426 expected_data[0 + 16] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1427 expected_data[2 + 16] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1428 expected_data[4 + 16] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);
1429
1430 expected_data[0 + 32] = Vec4(1.0f, 2.0f, 3.0f, 4.0f);
1431 expected_data[2 + 32] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1432 expected_data[4 + 32] = Vec4(30.0f, 40.0f, 0.0f, 1.0f);
1433 expected_data[0 + 16 + 32] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1434 expected_data[2 + 16 + 32] = Vec4(5.0f, 6.0f, 7.0f, 8.0f);
1435 expected_data[4 + 16 + 32] = Vec4(50.0f, 60.0f, 0.0f, 1.0f);
1436 return BasicInputBase::Run();
1437 }
1438 };
1439
1440 //=============================================================================
1441 // 1.2.12 BasicInputCase12
1442 //-----------------------------------------------------------------------------
1443 class BasicInputCase12 : public BasicInputBase
1444 {
1445 GLuint m_vao, m_vbo;
1446
Setup()1447 virtual long Setup()
1448 {
1449 BasicInputBase::Setup();
1450 glGenVertexArrays(1, &m_vao);
1451 glGenBuffers(1, &m_vbo);
1452 return NO_ERROR;
1453 }
1454
Cleanup()1455 virtual long Cleanup()
1456 {
1457 BasicInputBase::Cleanup();
1458 glDeleteVertexArrays(1, &m_vao);
1459 glDeleteBuffers(1, &m_vbo);
1460 return NO_ERROR;
1461 }
1462
Run()1463 virtual long Run()
1464 {
1465 for (GLuint i = 0; i < 16; ++i)
1466 {
1467 glVertexAttrib4f(i, 0.0f, 0.0f, 0.0f, 0.0f);
1468 }
1469 glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1470 glBufferData(GL_ARRAY_BUFFER, sizeof(Vec3) * 2, NULL, GL_STATIC_DRAW);
1471 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vec3), &Vec3(1.0f, 2.0f, 3.0f)[0]);
1472 glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(Vec3), &Vec3(4.0f, 5.0f, 6.0f)[0]);
1473 glBindBuffer(GL_ARRAY_BUFFER, 0);
1474
1475 glBindVertexArray(m_vao);
1476
1477 glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1478 glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 12, 0);
1479 glBindBuffer(GL_ARRAY_BUFFER, 0);
1480
1481 glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
1482 glVertexAttribBinding(0, 1);
1483
1484 glEnableVertexAttribArray(0);
1485 glEnableVertexAttribArray(1);
1486
1487 expected_data[0] = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
1488 expected_data[1] = Vec4(1.0f, 2.0f, 3.0f, 1.0f);
1489 expected_data[0 + 16] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
1490 expected_data[1 + 16] = Vec4(4.0f, 5.0f, 6.0f, 1.0f);
1491 return BasicInputBase::Run();
1492 }
1493 };
1494
1495 //=============================================================================
1496 // BasicInputIBase
1497 //-----------------------------------------------------------------------------
1498 class BasicInputIBase : public VertexAttribBindingBase
1499 {
1500 GLuint m_po, m_xfbo;
1501
1502 protected:
1503 IVec4 expected_datai[32];
1504 UVec4 expected_dataui[32];
1505 GLsizei instance_count;
1506 GLuint base_instance;
1507
Setup()1508 virtual long Setup()
1509 {
1510 m_po = 0;
1511 glGenBuffers(1, &m_xfbo);
1512 for (int i = 0; i < 32; ++i)
1513 {
1514 expected_datai[i] = IVec4(0);
1515 expected_dataui[i] = UVec4(0);
1516 }
1517 instance_count = 1;
1518 base_instance = 0;
1519 return NO_ERROR;
1520 }
1521
Cleanup()1522 virtual long Cleanup()
1523 {
1524 glDisable(GL_RASTERIZER_DISCARD);
1525 glUseProgram(0);
1526 glDeleteProgram(m_po);
1527 glDeleteBuffers(1, &m_xfbo);
1528 return NO_ERROR;
1529 }
1530
Run()1531 virtual long Run()
1532 {
1533 const char* const glsl_vs =
1534 "#version 430 core" NL "layout(location = 0) in ivec4 vs_in_attribi[8];" NL
1535 "layout(location = 8) in uvec4 vs_in_attribui[8];" NL "out StageData {" NL " ivec4 attribi[8];" NL
1536 " uvec4 attribui[8];" NL "} vs_out;" NL "void main() {" NL
1537 " for (int i = 0; i < vs_in_attribi.length(); ++i) {" NL " vs_out.attribi[i] = vs_in_attribi[i];" NL
1538 " }" NL " for (int i = 0; i < vs_in_attribui.length(); ++i) {" NL
1539 " vs_out.attribui[i] = vs_in_attribui[i];" NL " }" NL "}";
1540 m_po = glCreateProgram();
1541 {
1542 const GLuint sh = glCreateShader(GL_VERTEX_SHADER);
1543 glShaderSource(sh, 1, &glsl_vs, NULL);
1544 glCompileShader(sh);
1545 glAttachShader(m_po, sh);
1546 glDeleteShader(sh);
1547 }
1548 {
1549 const GLchar* const v[16] = { "StageData.attribi[0]", "StageData.attribi[1]", "StageData.attribi[2]",
1550 "StageData.attribi[3]", "StageData.attribi[4]", "StageData.attribi[5]",
1551 "StageData.attribi[6]", "StageData.attribi[7]", "StageData.attribui[0]",
1552 "StageData.attribui[1]", "StageData.attribui[2]", "StageData.attribui[3]",
1553 "StageData.attribui[4]", "StageData.attribui[5]", "StageData.attribui[6]",
1554 "StageData.attribui[7]" };
1555 glTransformFeedbackVaryings(m_po, 16, v, GL_INTERLEAVED_ATTRIBS);
1556 }
1557 glLinkProgram(m_po);
1558 if (!CheckProgram(m_po))
1559 return ERROR;
1560
1561 {
1562 std::vector<GLubyte> zero(64 * 16);
1563 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_xfbo);
1564 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, (GLsizeiptr)zero.size(), &zero[0], GL_DYNAMIC_COPY);
1565 }
1566
1567 glEnable(GL_RASTERIZER_DISCARD);
1568 glUseProgram(m_po);
1569 glBeginTransformFeedback(GL_POINTS);
1570 glDrawArraysInstancedBaseInstance(GL_POINTS, 0, 2, instance_count, base_instance);
1571 glEndTransformFeedback();
1572
1573 IVec4 datai[32];
1574 glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0 * 16 * 8, 16 * 8, &datai[0]);
1575 glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 2 * 16 * 8, 16 * 8, &datai[8]);
1576 glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 4 * 16 * 8, 16 * 8, &datai[16]);
1577 glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 6 * 16 * 8, 16 * 8, &datai[24]);
1578 UVec4 dataui[32];
1579 glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 1 * 16 * 8, 16 * 8, &dataui[0]);
1580 glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 3 * 16 * 8, 16 * 8, &dataui[8]);
1581 glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 5 * 16 * 8, 16 * 8, &dataui[16]);
1582 glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 7 * 16 * 8, 16 * 8, &dataui[24]);
1583
1584 for (int i = 0; i < 32; ++i)
1585 {
1586 if (!IsEqual(expected_datai[i], datai[i]))
1587 {
1588 m_context.getTestContext().getLog()
1589 << tcu::TestLog::Message << "Datai is: " << datai[i][0] << " " << datai[i][1] << " " << datai[i][2]
1590 << " " << datai[i][3] << ", datai should be: " << expected_datai[i][0] << " "
1591 << expected_datai[i][1] << " " << expected_datai[i][2] << " " << expected_datai[i][3]
1592 << ", index is: " << i << tcu::TestLog::EndMessage;
1593 return ERROR;
1594 }
1595 if (!IsEqual(expected_dataui[i], dataui[i]))
1596 {
1597 m_context.getTestContext().getLog()
1598 << tcu::TestLog::Message << "Dataui is: " << dataui[i][0] << " " << dataui[i][1] << " "
1599 << dataui[i][2] << " " << dataui[i][3] << ", dataui should be: " << expected_dataui[i][0] << " "
1600 << expected_dataui[i][1] << " " << expected_dataui[i][2] << " " << expected_dataui[i][3]
1601 << ", index is: " << i << tcu::TestLog::EndMessage;
1602 return ERROR;
1603 }
1604 }
1605 return NO_ERROR;
1606 }
1607 };
1608
1609 //=============================================================================
1610 // 1.3.1 BasicInputICase1
1611 //-----------------------------------------------------------------------------
1612 class BasicInputICase1 : public BasicInputIBase
1613 {
1614 GLuint m_vao, m_vbo;
1615
Setup()1616 virtual long Setup()
1617 {
1618 BasicInputIBase::Setup();
1619 glGenVertexArrays(1, &m_vao);
1620 glGenBuffers(1, &m_vbo);
1621 return NO_ERROR;
1622 }
1623
Cleanup()1624 virtual long Cleanup()
1625 {
1626 BasicInputIBase::Cleanup();
1627 glDeleteVertexArrays(1, &m_vao);
1628 glDeleteBuffers(1, &m_vbo);
1629 return NO_ERROR;
1630 }
1631
Run()1632 virtual long Run()
1633 {
1634 for (GLuint i = 0; i < 8; ++i)
1635 {
1636 glVertexAttribI4i(i, 0, 0, 0, 0);
1637 glVertexAttribI4ui(i + 8, 0, 0, 0, 0);
1638 }
1639 const int kStride = 88;
1640 glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1641 glBufferData(GL_ARRAY_BUFFER, kStride * 2, NULL, GL_STATIC_DRAW);
1642 {
1643 GLbyte d[] = { 1, -2, 3, -4 };
1644 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(d), d);
1645 }
1646 {
1647 GLshort d[] = { 5, -6, 7, -8 };
1648 glBufferSubData(GL_ARRAY_BUFFER, 4, sizeof(d), d);
1649 }
1650 {
1651 GLint d[] = { 9, -10, 11, -12 };
1652 glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(d), d);
1653 }
1654 {
1655 GLubyte d[] = { 13, 14, 15, 16 };
1656 glBufferSubData(GL_ARRAY_BUFFER, 28, sizeof(d), d);
1657 }
1658 {
1659 GLushort d[] = { 17, 18, 19, 20 };
1660 glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(d), d);
1661 }
1662 {
1663 GLuint d[] = { 21, 22, 23, 24 };
1664 glBufferSubData(GL_ARRAY_BUFFER, 40, sizeof(d), d);
1665 }
1666 {
1667 GLint d[] = { 90, -91, 92, -93 };
1668 glBufferSubData(GL_ARRAY_BUFFER, 56, sizeof(d), d);
1669 }
1670 {
1671 GLuint d[] = { 94, 95, 96, 97 };
1672 glBufferSubData(GL_ARRAY_BUFFER, 72, sizeof(d), d);
1673 }
1674
1675 {
1676 GLbyte d[] = { 25, -26, 27, -28 };
1677 glBufferSubData(GL_ARRAY_BUFFER, 0 + kStride, sizeof(d), d);
1678 }
1679 {
1680 GLshort d[] = { 29, -30, 31, -32 };
1681 glBufferSubData(GL_ARRAY_BUFFER, 4 + kStride, sizeof(d), d);
1682 }
1683 {
1684 GLint d[] = { 33, -34, 35, -36 };
1685 glBufferSubData(GL_ARRAY_BUFFER, 12 + kStride, sizeof(d), d);
1686 }
1687 {
1688 GLubyte d[] = { 37, 38, 39, 40 };
1689 glBufferSubData(GL_ARRAY_BUFFER, 28 + kStride, sizeof(d), d);
1690 }
1691 {
1692 GLushort d[] = { 41, 42, 43, 44 };
1693 glBufferSubData(GL_ARRAY_BUFFER, 32 + kStride, sizeof(d), d);
1694 }
1695 {
1696 GLuint d[] = { 45, 46, 47, 48 };
1697 glBufferSubData(GL_ARRAY_BUFFER, 40 + kStride, sizeof(d), d);
1698 }
1699 {
1700 GLint d[] = { 98, -99, 100, -101 };
1701 glBufferSubData(GL_ARRAY_BUFFER, 56 + kStride, sizeof(d), d);
1702 }
1703 {
1704 GLuint d[] = { 102, 103, 104, 105 };
1705 glBufferSubData(GL_ARRAY_BUFFER, 72 + kStride, sizeof(d), d);
1706 }
1707 glBindBuffer(GL_ARRAY_BUFFER, 0);
1708
1709 glBindVertexArray(m_vao);
1710 glVertexAttribIFormat(0, 1, GL_BYTE, 0);
1711 glVertexAttribIFormat(1, 2, GL_SHORT, 4);
1712 glVertexAttribIFormat(2, 3, GL_INT, 12);
1713 glVertexAttribIFormat(3, 4, GL_INT, 56);
1714 glVertexAttribIFormat(8, 3, GL_UNSIGNED_BYTE, 28);
1715 glVertexAttribIFormat(9, 2, GL_UNSIGNED_SHORT, 32);
1716 glVertexAttribIFormat(10, 1, GL_UNSIGNED_INT, 40);
1717 glVertexAttribIFormat(11, 4, GL_UNSIGNED_INT, 72);
1718 glVertexAttribBinding(0, 0);
1719 glVertexAttribBinding(1, 0);
1720 glVertexAttribBinding(2, 0);
1721 glVertexAttribBinding(3, 0);
1722 glVertexAttribBinding(8, 0);
1723 glVertexAttribBinding(9, 0);
1724 glVertexAttribBinding(10, 0);
1725 glVertexAttribBinding(11, 0);
1726 glBindVertexBuffer(0, m_vbo, 0, kStride);
1727 glEnableVertexAttribArray(0);
1728 glEnableVertexAttribArray(1);
1729 glEnableVertexAttribArray(2);
1730 glEnableVertexAttribArray(3);
1731 glEnableVertexAttribArray(8);
1732 glEnableVertexAttribArray(9);
1733 glEnableVertexAttribArray(10);
1734 glEnableVertexAttribArray(11);
1735
1736 expected_datai[0] = IVec4(1, 0, 0, 1);
1737 expected_datai[1] = IVec4(5, -6, 0, 1);
1738 expected_datai[2] = IVec4(9, -10, 11, 1);
1739 expected_datai[3] = IVec4(90, -91, 92, -93);
1740 expected_dataui[0] = UVec4(13, 14, 15, 1);
1741 expected_dataui[1] = UVec4(17, 18, 0, 1);
1742 expected_dataui[2] = UVec4(21, 0, 0, 1);
1743 expected_dataui[3] = UVec4(94, 95, 96, 97);
1744 expected_datai[8] = IVec4(25, 0, 0, 1);
1745 expected_datai[9] = IVec4(29, -30, 0, 1);
1746 expected_datai[10] = IVec4(33, -34, 35, 1);
1747 expected_datai[11] = IVec4(98, -99, 100, -101);
1748 expected_dataui[8] = UVec4(37, 38, 39, 1);
1749 expected_dataui[9] = UVec4(41, 42, 0, 1);
1750 expected_dataui[10] = UVec4(45, 0, 0, 1);
1751 expected_dataui[11] = UVec4(102, 103, 104, 105);
1752 return BasicInputIBase::Run();
1753 }
1754 };
1755
1756 //=============================================================================
1757 // 1.3.2 BasicInputICase2
1758 //-----------------------------------------------------------------------------
1759 class BasicInputICase2 : public BasicInputIBase
1760 {
1761 GLuint m_vao, m_vbo[2];
1762
Setup()1763 virtual long Setup()
1764 {
1765 BasicInputIBase::Setup();
1766 glGenVertexArrays(1, &m_vao);
1767 glGenBuffers(2, m_vbo);
1768 return NO_ERROR;
1769 }
1770
Cleanup()1771 virtual long Cleanup()
1772 {
1773 BasicInputIBase::Cleanup();
1774 glDeleteVertexArrays(1, &m_vao);
1775 glDeleteBuffers(2, m_vbo);
1776 return NO_ERROR;
1777 }
1778
Run()1779 virtual long Run()
1780 {
1781 for (GLuint i = 0; i < 8; ++i)
1782 {
1783 glVertexAttribI4i(i, 0, 0, 0, 0);
1784 glVertexAttribI4ui(i + 8, 0, 0, 0, 0);
1785 }
1786 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
1787 glBufferData(GL_ARRAY_BUFFER, sizeof(IVec3) * 2, NULL, GL_STATIC_DRAW);
1788 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(IVec3), &IVec3(1, 2, 3)[0]);
1789 glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(IVec3), &IVec3(4, 5, 6)[0]);
1790
1791 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
1792 glBufferData(GL_ARRAY_BUFFER, sizeof(UVec4), NULL, GL_STATIC_DRAW);
1793 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(UVec4), &UVec4(10, 20, 30, 40)[0]);
1794 glBindBuffer(GL_ARRAY_BUFFER, 0);
1795
1796 glBindVertexArray(m_vao);
1797 glVertexAttribIFormat(0, 3, GL_INT, 0);
1798 glVertexAttribIFormat(2, 2, GL_INT, 4);
1799 glVertexAttribIFormat(15, 1, GL_UNSIGNED_INT, 0);
1800 glVertexAttribBinding(0, 2);
1801 glVertexAttribBinding(2, 0);
1802 glVertexAttribBinding(15, 7);
1803 glEnableVertexAttribArray(0);
1804 glEnableVertexAttribArray(2);
1805 glEnableVertexAttribArray(15);
1806 glBindVertexBuffer(0, m_vbo[0], 0, 8);
1807 glBindVertexBuffer(2, m_vbo[0], 0, 12);
1808 glBindVertexBuffer(7, m_vbo[1], 4, 16);
1809 glVertexBindingDivisor(0, 1);
1810 glVertexBindingDivisor(2, 0);
1811 glVertexBindingDivisor(7, 2);
1812
1813 instance_count = 2;
1814 expected_datai[0] = IVec4(1, 2, 3, 1);
1815 expected_datai[2] = IVec4(2, 3, 0, 1);
1816 expected_dataui[7] = UVec4(20, 0, 0, 1);
1817 expected_datai[8] = IVec4(4, 5, 6, 1);
1818 expected_datai[10] = IVec4(2, 3, 0, 1);
1819 expected_dataui[15] = UVec4(20, 0, 0, 1);
1820
1821 expected_datai[16] = IVec4(1, 2, 3, 1);
1822 expected_datai[18] = IVec4(4, 5, 0, 1);
1823 expected_dataui[23] = UVec4(20, 0, 0, 1);
1824 expected_datai[24] = IVec4(4, 5, 6, 1);
1825 expected_datai[26] = IVec4(4, 5, 0, 1);
1826 expected_dataui[31] = UVec4(20, 0, 0, 1);
1827 return BasicInputIBase::Run();
1828 }
1829 };
1830
1831 //=============================================================================
1832 // 1.3.3 BasicInputICase3
1833 //-----------------------------------------------------------------------------
1834 class BasicInputICase3 : public BasicInputIBase
1835 {
1836 GLuint m_vao, m_vbo;
1837
Setup()1838 virtual long Setup()
1839 {
1840 BasicInputIBase::Setup();
1841 glGenVertexArrays(1, &m_vao);
1842 glGenBuffers(1, &m_vbo);
1843 return NO_ERROR;
1844 }
1845
Cleanup()1846 virtual long Cleanup()
1847 {
1848 BasicInputIBase::Cleanup();
1849 glDeleteVertexArrays(1, &m_vao);
1850 glDeleteBuffers(1, &m_vbo);
1851 return NO_ERROR;
1852 }
1853
Run()1854 virtual long Run()
1855 {
1856 for (GLuint i = 0; i < 8; ++i)
1857 {
1858 glVertexAttribI4i(i, 0, 0, 0, 0);
1859 glVertexAttribI4ui(i + 8, 0, 0, 0, 0);
1860 }
1861 glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1862 glBufferData(GL_ARRAY_BUFFER, sizeof(IVec3) * 2, NULL, GL_STATIC_DRAW);
1863 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(IVec3), &IVec3(1, 2, 3)[0]);
1864 glBufferSubData(GL_ARRAY_BUFFER, 12, sizeof(IVec3), &IVec3(4, 5, 6)[0]);
1865 glBindBuffer(GL_ARRAY_BUFFER, 0);
1866
1867 glBindVertexArray(m_vao);
1868
1869 glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
1870 glVertexAttribIPointer(7, 3, GL_INT, 12, 0);
1871 glBindBuffer(GL_ARRAY_BUFFER, 0);
1872
1873 glVertexAttribIFormat(0, 2, GL_INT, 4);
1874 glVertexAttribBinding(0, 7);
1875
1876 glEnableVertexAttribArray(0);
1877 glEnableVertexAttribArray(7);
1878
1879 expected_datai[0] = IVec4(2, 3, 0, 1);
1880 expected_datai[7] = IVec4(1, 2, 3, 1);
1881 expected_datai[0 + 8] = IVec4(5, 6, 0, 1);
1882 expected_datai[7 + 8] = IVec4(4, 5, 6, 1);
1883 return BasicInputIBase::Run();
1884 }
1885 };
1886
1887 //=============================================================================
1888 // BasicInputLBase
1889 //-----------------------------------------------------------------------------
1890 class BasicInputLBase : public VertexAttribBindingBase
1891 {
1892 GLuint m_po, m_xfbo;
1893
1894 protected:
1895 DVec4 expected_data[32];
1896 GLsizei instance_count;
1897 GLuint base_instance;
1898
Setup()1899 virtual long Setup()
1900 {
1901 m_po = 0;
1902 glGenBuffers(1, &m_xfbo);
1903 for (int i = 0; i < 32; ++i)
1904 {
1905 expected_data[i] = DVec4(0.0);
1906 }
1907 instance_count = 1;
1908 base_instance = 0;
1909 return NO_ERROR;
1910 }
1911
Cleanup()1912 virtual long Cleanup()
1913 {
1914 glDisable(GL_RASTERIZER_DISCARD);
1915 glUseProgram(0);
1916 glDeleteProgram(m_po);
1917 glDeleteBuffers(1, &m_xfbo);
1918 return NO_ERROR;
1919 }
1920
Run()1921 virtual long Run()
1922 {
1923 const char* const glsl_vs =
1924 "#version 430 core" NL "layout(location = 0) in dvec4 vs_in_attrib[8];" NL "out StageData {" NL
1925 " dvec4 attrib[8];" NL "} vs_out;" NL "void main() {" NL " vs_out.attrib[0] = vs_in_attrib[0];" NL
1926 " vs_out.attrib[1] = vs_in_attrib[1];" NL " vs_out.attrib[2] = vs_in_attrib[2];" NL
1927 " vs_out.attrib[3] = vs_in_attrib[3];" NL " vs_out.attrib[4] = vs_in_attrib[4];" NL
1928 " vs_out.attrib[5] = vs_in_attrib[5];" NL " vs_out.attrib[6] = vs_in_attrib[6];" NL
1929 " vs_out.attrib[7] = vs_in_attrib[7];" NL "}";
1930 m_po = glCreateProgram();
1931 {
1932 const GLuint sh = glCreateShader(GL_VERTEX_SHADER);
1933 glShaderSource(sh, 1, &glsl_vs, NULL);
1934 glCompileShader(sh);
1935 glAttachShader(m_po, sh);
1936 glDeleteShader(sh);
1937 }
1938 {
1939 const GLchar* const v[8] = {
1940 "StageData.attrib[0]", "StageData.attrib[1]", "StageData.attrib[2]", "StageData.attrib[3]",
1941 "StageData.attrib[4]", "StageData.attrib[5]", "StageData.attrib[6]", "StageData.attrib[7]",
1942 };
1943 glTransformFeedbackVaryings(m_po, 8, v, GL_INTERLEAVED_ATTRIBS);
1944 }
1945 glLinkProgram(m_po);
1946 if (!CheckProgram(m_po))
1947 return ERROR;
1948
1949 {
1950 std::vector<GLubyte> zero(sizeof(expected_data));
1951 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_xfbo);
1952 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, (GLsizeiptr)zero.size(), &zero[0], GL_DYNAMIC_COPY);
1953 }
1954
1955 glEnable(GL_RASTERIZER_DISCARD);
1956 glUseProgram(m_po);
1957 glBeginTransformFeedback(GL_POINTS);
1958 glDrawArraysInstancedBaseInstance(GL_POINTS, 0, 2, instance_count, base_instance);
1959 glEndTransformFeedback();
1960
1961 DVec4 data[32];
1962 glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, sizeof(DVec4) * 32, &data[0]);
1963
1964 for (int i = 0; i < 32; ++i)
1965 {
1966 for (int j = 0; j < 4; ++j)
1967 {
1968 if (expected_data[i][j] != 12345.0 && expected_data[i][j] != data[i][j])
1969 {
1970 m_context.getTestContext().getLog()
1971 << tcu::TestLog::Message << "Data is: " << data[i][0] << " " << data[i][1] << " " << data[i][2]
1972 << " " << data[i][3] << ", data should be: " << expected_data[i][0] << " "
1973 << expected_data[i][1] << " " << expected_data[i][2] << " " << expected_data[i][3]
1974 << ", index is: " << i << tcu::TestLog::EndMessage;
1975 return ERROR;
1976 }
1977 }
1978 }
1979 return NO_ERROR;
1980 }
1981 };
1982
1983 //=============================================================================
1984 // 1.4.1 BasicInputLCase1
1985 //-----------------------------------------------------------------------------
1986 class BasicInputLCase1 : public BasicInputLBase
1987 {
1988 GLuint m_vao, m_vbo;
1989
Setup()1990 virtual long Setup()
1991 {
1992 BasicInputLBase::Setup();
1993 glGenVertexArrays(1, &m_vao);
1994 glGenBuffers(1, &m_vbo);
1995 return NO_ERROR;
1996 }
1997
Cleanup()1998 virtual long Cleanup()
1999 {
2000 BasicInputLBase::Cleanup();
2001 glDeleteVertexArrays(1, &m_vao);
2002 glDeleteBuffers(1, &m_vbo);
2003 return NO_ERROR;
2004 }
2005
Run()2006 virtual long Run()
2007 {
2008 for (GLuint i = 0; i < 8; ++i)
2009 {
2010 glVertexAttribL4d(i, 0.0, 0.0, 0.0, 0.0);
2011 }
2012 glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
2013 glBufferData(GL_ARRAY_BUFFER, sizeof(DVec4) * 3, NULL, GL_STATIC_DRAW);
2014 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(DVec4), &DVec4(1.0, 2.0, 3.0, 4.0)[0]);
2015 glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(DVec4), &DVec4(5.0, 6.0, 7.0, 8.0)[0]);
2016 glBufferSubData(GL_ARRAY_BUFFER, 64, sizeof(DVec4), &DVec4(9.0, 10.0, 11.0, 12.0)[0]);
2017 glBindBuffer(GL_ARRAY_BUFFER, 0);
2018
2019 glBindVertexArray(m_vao);
2020 glVertexAttribLFormat(0, 4, GL_DOUBLE, 0);
2021 glVertexAttribLFormat(3, 3, GL_DOUBLE, 8);
2022 glVertexAttribLFormat(5, 2, GL_DOUBLE, 0);
2023 glVertexAttribLFormat(7, 1, GL_DOUBLE, 24);
2024 glVertexAttribBinding(0, 0);
2025 glVertexAttribBinding(3, 2);
2026 glVertexAttribBinding(5, 0);
2027 glVertexAttribBinding(7, 6);
2028 glEnableVertexAttribArray(0);
2029 glEnableVertexAttribArray(3);
2030 glEnableVertexAttribArray(5);
2031 glEnableVertexAttribArray(7);
2032 glBindVertexBuffer(0, m_vbo, 0, 32);
2033 glBindVertexBuffer(2, m_vbo, 0, 16);
2034 glBindVertexBuffer(6, m_vbo, 16, 0);
2035
2036 expected_data[0] = DVec4(1.0, 2.0, 3.0, 4.0);
2037 expected_data[3] = DVec4(2.0, 3.0, 4.0, 12345.0);
2038 expected_data[5] = DVec4(1.0, 2.0, 12345.0, 12345.0);
2039 expected_data[7] = DVec4(6.0, 12345.0, 12345.0, 12345.0);
2040 expected_data[0 + 8] = DVec4(5.0, 6.0, 7.0, 8.0);
2041 expected_data[3 + 8] = DVec4(4.0, 5.0, 6.0, 12345.0);
2042 expected_data[5 + 8] = DVec4(5.0, 6.0, 12345.0, 12345.0);
2043 expected_data[7 + 8] = DVec4(6.0, 12345.0, 12345.0, 12345.0);
2044 return BasicInputLBase::Run();
2045 }
2046 };
2047
2048 //=============================================================================
2049 // 1.4.2 BasicInputLCase2
2050 //-----------------------------------------------------------------------------
2051 class BasicInputLCase2 : public BasicInputLBase
2052 {
2053 GLuint m_vao, m_vbo[2];
2054
Setup()2055 virtual long Setup()
2056 {
2057 BasicInputLBase::Setup();
2058 glGenVertexArrays(1, &m_vao);
2059 glGenBuffers(2, m_vbo);
2060 return NO_ERROR;
2061 }
2062
Cleanup()2063 virtual long Cleanup()
2064 {
2065 BasicInputLBase::Cleanup();
2066 glDeleteVertexArrays(1, &m_vao);
2067 glDeleteBuffers(2, m_vbo);
2068 return NO_ERROR;
2069 }
2070
Run()2071 virtual long Run()
2072 {
2073 for (GLuint i = 0; i < 8; ++i)
2074 {
2075 glVertexAttribL4d(i, 0.0, 0.0, 0.0, 0.0);
2076 }
2077 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
2078 glBufferData(GL_ARRAY_BUFFER, sizeof(DVec4) * 3, NULL, GL_STATIC_DRAW);
2079 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(DVec4), &DVec4(1.0, 2.0, 3.0, 4.0)[0]);
2080 glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(DVec4), &DVec4(5.0, 6.0, 7.0, 8.0)[0]);
2081 glBufferSubData(GL_ARRAY_BUFFER, 64, sizeof(DVec4), &DVec4(9.0, 10.0, 11.0, 12.0)[0]);
2082 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
2083 glBufferData(GL_ARRAY_BUFFER, sizeof(DVec4) * 3, NULL, GL_STATIC_DRAW);
2084 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(DVec4), &DVec4(10.0, 20.0, 30.0, 40.0)[0]);
2085 glBufferSubData(GL_ARRAY_BUFFER, 32, sizeof(DVec4), &DVec4(50.0, 60.0, 70.0, 80.0)[0]);
2086 glBindBuffer(GL_ARRAY_BUFFER, 0);
2087
2088 glBindVertexArray(m_vao);
2089 glVertexAttribLFormat(0, 4, GL_DOUBLE, 0);
2090 glVertexAttribLFormat(2, 4, GL_DOUBLE, 0);
2091 glVertexAttribLFormat(4, 2, GL_DOUBLE, 8);
2092 glVertexAttribBinding(0, 0);
2093 glVertexAttribBinding(2, 1);
2094 glVertexAttribBinding(4, 2);
2095 glEnableVertexAttribArray(0);
2096 glEnableVertexAttribArray(2);
2097 glEnableVertexAttribArray(4);
2098 glBindVertexBuffer(0, m_vbo[0], 0, 32);
2099 glBindVertexBuffer(1, m_vbo[0], 0, 32);
2100 glBindVertexBuffer(2, m_vbo[1], 8, 16);
2101 glVertexBindingDivisor(1, 1);
2102
2103 instance_count = 2;
2104 expected_data[0] = DVec4(1.0, 2.0, 3.0, 4.0);
2105 expected_data[2] = DVec4(1.0, 2.0, 3.0, 4.0);
2106 expected_data[4] = DVec4(30.0, 40.0, 12345.0, 12345.0);
2107 expected_data[0 + 8] = DVec4(5.0, 6.0, 7.0, 8.0);
2108 expected_data[2 + 8] = DVec4(1.0, 2.0, 3.0, 4.0);
2109 expected_data[4 + 8] = DVec4(50.0, 60.0, 12345.0, 12345.0);
2110
2111 expected_data[0 + 16] = DVec4(1.0, 2.0, 3.0, 4.0);
2112 expected_data[2 + 16] = DVec4(5.0, 6.0, 7.0, 8.0);
2113 expected_data[4 + 16] = DVec4(30.0, 40.0, 12345.0, 12345.0);
2114 expected_data[0 + 8 + 16] = DVec4(5.0, 6.0, 7.0, 8.0);
2115 expected_data[2 + 8 + 16] = DVec4(5.0, 6.0, 7.0, 8.0);
2116 expected_data[4 + 8 + 16] = DVec4(50.0, 60.0, 12345.0, 12345.0);
2117 return BasicInputLBase::Run();
2118 }
2119 };
2120
2121 //=============================================================================
2122 // 1.5 BasicState1
2123 //-----------------------------------------------------------------------------
2124 class BasicState1 : public VertexAttribBindingBase
2125 {
2126 GLuint m_vao, m_vbo[2];
2127
Setup()2128 virtual long Setup()
2129 {
2130 glGenVertexArrays(1, &m_vao);
2131 glGenBuffers(2, m_vbo);
2132 return NO_ERROR;
2133 }
2134
Cleanup()2135 virtual long Cleanup()
2136 {
2137 glDeleteVertexArrays(1, &m_vao);
2138 glDeleteBuffers(2, m_vbo);
2139 return NO_ERROR;
2140 }
2141
Run()2142 virtual long Run()
2143 {
2144 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
2145 glBufferData(GL_ARRAY_BUFFER, 1000, NULL, GL_DYNAMIC_COPY);
2146 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
2147 glBufferData(GL_ARRAY_BUFFER, 1000, NULL, GL_DYNAMIC_COPY);
2148 glBindBuffer(GL_ARRAY_BUFFER, 0);
2149
2150 GLint p;
2151 glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &p);
2152 if (p < 16)
2153 {
2154 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_BINDINGS is " << p
2155 << " but must be at least 16." << tcu::TestLog::EndMessage;
2156 return ERROR;
2157 }
2158 glGetIntegerv(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
2159 if (p < 2047)
2160 {
2161 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET is "
2162 << p << " but must be at least 2047." << tcu::TestLog::EndMessage;
2163 return ERROR;
2164 }
2165
2166 glBindVertexArray(m_vao);
2167 // check default state
2168 for (GLuint i = 0; i < 16; ++i)
2169 {
2170 glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_BINDING, &p);
2171 if (static_cast<GLint>(i) != p)
2172 {
2173 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_BINDING(" << i
2174 << ") is " << p << " should be " << i << tcu::TestLog::EndMessage;
2175 return ERROR;
2176 }
2177 glGetVertexAttribiv(i, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
2178 if (p != 0)
2179 {
2180 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_RELATIVE_OFFSET(" << i
2181 << ") is " << p << " should be 0." << tcu::TestLog::EndMessage;
2182 return ERROR;
2183 }
2184 GLint64 p64;
2185 glGetInteger64i_v(GL_VERTEX_BINDING_OFFSET, i, &p64);
2186 if (p64 != 0)
2187 {
2188 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_OFFSET(" << i
2189 << ") should be 0." << tcu::TestLog::EndMessage;
2190 return ERROR;
2191 }
2192 glGetIntegeri_v(GL_VERTEX_BINDING_STRIDE, i, &p);
2193 if (p != 16)
2194 {
2195 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_STRIDE(" << i
2196 << ") is " << p << " should be 16." << tcu::TestLog::EndMessage;
2197 return ERROR;
2198 }
2199 }
2200 glVertexAttribFormat(0, 2, GL_BYTE, GL_TRUE, 16);
2201 glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_SIZE, &p);
2202 if (p != 2)
2203 {
2204 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_SIZE(0) is " << p
2205 << " should be 2." << tcu::TestLog::EndMessage;
2206 return ERROR;
2207 }
2208 glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_TYPE, &p);
2209 if (p != GL_BYTE)
2210 {
2211 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_TYPE(0) is " << p
2212 << " should be GL_BYTE." << tcu::TestLog::EndMessage;
2213 return ERROR;
2214 }
2215 glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &p);
2216 if (p != GL_TRUE)
2217 {
2218 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED(0) is "
2219 << p << " should be GL_TRUE." << tcu::TestLog::EndMessage;
2220 return ERROR;
2221 }
2222 glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
2223 if (p != 16)
2224 {
2225 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_RELATIVE_OFFSET(0) is "
2226 << p << " should be 16." << tcu::TestLog::EndMessage;
2227 return ERROR;
2228 }
2229
2230 glVertexAttribIFormat(2, 3, GL_INT, 512);
2231 glGetVertexAttribiv(2, GL_VERTEX_ATTRIB_ARRAY_SIZE, &p);
2232 if (p != 3)
2233 {
2234 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_SIZE(2) is " << p
2235 << " should be 3." << tcu::TestLog::EndMessage;
2236 return ERROR;
2237 }
2238 glGetVertexAttribiv(2, GL_VERTEX_ATTRIB_ARRAY_TYPE, &p);
2239 if (p != GL_INT)
2240 {
2241 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_TYPE(2) is " << p
2242 << " should be GL_INT." << tcu::TestLog::EndMessage;
2243 return ERROR;
2244 }
2245 glGetVertexAttribiv(2, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
2246 if (p != 512)
2247 {
2248 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_RELATIVE_OFFSET(2) is "
2249 << p << " should be 512." << tcu::TestLog::EndMessage;
2250 return ERROR;
2251 }
2252 glGetVertexAttribiv(2, GL_VERTEX_ATTRIB_ARRAY_INTEGER, &p);
2253 if (p != GL_TRUE)
2254 {
2255 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_INTEGER(2) is " << p
2256 << " should be GL_TRUE." << tcu::TestLog::EndMessage;
2257 return ERROR;
2258 }
2259
2260 glVertexAttribLFormat(15, 1, GL_DOUBLE, 1024);
2261 glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_ARRAY_SIZE, &p);
2262 if (p != 1)
2263 {
2264 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_SIZE(15) is " << p
2265 << " should be 1." << tcu::TestLog::EndMessage;
2266 return ERROR;
2267 }
2268 glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_ARRAY_TYPE, &p);
2269 if (p != GL_DOUBLE)
2270 {
2271 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_TYPE(15) is " << p
2272 << " should be GL_DOUBLE." << tcu::TestLog::EndMessage;
2273 return ERROR;
2274 }
2275 glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
2276 if (p != 1024)
2277 {
2278 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_TYPE(15) is " << p
2279 << " should be 1024." << tcu::TestLog::EndMessage;
2280 return ERROR;
2281 }
2282 glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_ARRAY_LONG, &p);
2283 if (p != GL_TRUE)
2284 {
2285 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_LONG(15) is " << p
2286 << " should be GL_TRUE." << tcu::TestLog::EndMessage;
2287 return ERROR;
2288 }
2289
2290 glVertexAttribBinding(0, 7);
2291 glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_BINDING, &p);
2292 if (p != 7)
2293 return ERROR;
2294 glVertexAttribBinding(3, 7);
2295 glGetVertexAttribiv(3, GL_VERTEX_ATTRIB_BINDING, &p);
2296 if (p != 7)
2297 return ERROR;
2298 glVertexAttribBinding(9, 0);
2299 glGetVertexAttribiv(9, GL_VERTEX_ATTRIB_BINDING, &p);
2300 if (p != 0)
2301 return ERROR;
2302 glVertexAttribBinding(15, 1);
2303 glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_BINDING, &p);
2304 if (p != 1)
2305 return ERROR;
2306 glVertexAttribBinding(15, 15);
2307 glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_BINDING, &p);
2308 if (p != 15)
2309 return ERROR;
2310
2311 glBindVertexBuffer(0, m_vbo[0], 1024, 128);
2312 GLint64 p64;
2313 glGetInteger64i_v(GL_VERTEX_BINDING_OFFSET, 0, &p64);
2314 if (p64 != 1024)
2315 {
2316 m_context.getTestContext().getLog()
2317 << tcu::TestLog::Message << "GL_VERTEX_BINDING_OFFSET(0) should be 1024." << tcu::TestLog::EndMessage;
2318 return ERROR;
2319 }
2320 glGetIntegeri_v(GL_VERTEX_BINDING_STRIDE, 0, &p);
2321 if (p != 128)
2322 {
2323 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_STRIDE(0) is " << p
2324 << "should be 128." << tcu::TestLog::EndMessage;
2325 return ERROR;
2326 }
2327 glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &p);
2328 if (p != 0)
2329 {
2330 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_STRIDE(0) is " << p
2331 << "should be 0." << tcu::TestLog::EndMessage;
2332 return ERROR;
2333 }
2334 glGetVertexAttribiv(0, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &p);
2335 if (p != 0)
2336 {
2337 m_context.getTestContext().getLog()
2338 << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING(0) is " << p << "should be 0."
2339 << tcu::TestLog::EndMessage;
2340 return ERROR;
2341 }
2342
2343 glBindVertexBuffer(15, m_vbo[1], 16, 32);
2344 glGetInteger64i_v(GL_VERTEX_BINDING_OFFSET, 15, &p64);
2345 if (p64 != 16)
2346 {
2347 m_context.getTestContext().getLog()
2348 << tcu::TestLog::Message << "GL_VERTEX_BINDING_OFFSET(15) should be 16." << tcu::TestLog::EndMessage;
2349 return ERROR;
2350 }
2351 glGetIntegeri_v(GL_VERTEX_BINDING_STRIDE, 15, &p);
2352 if (p != 32)
2353 {
2354 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_STRIDE(15) is " << p
2355 << " should be 32." << tcu::TestLog::EndMessage;
2356 return ERROR;
2357 }
2358 glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &p);
2359 if (p != 0)
2360 {
2361 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_STRIDE(15) is " << p
2362 << " should be 0." << tcu::TestLog::EndMessage;
2363 return ERROR;
2364 }
2365 glGetVertexAttribiv(15, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &p);
2366 if (p != static_cast<GLint>(m_vbo[1]))
2367 {
2368 m_context.getTestContext().getLog()
2369 << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING(15) is " << p << " should be "
2370 << m_vbo[1] << tcu::TestLog::EndMessage;
2371 return ERROR;
2372 }
2373
2374 return NO_ERROR;
2375 }
2376 };
2377
2378 //=============================================================================
2379 // 1.6 BasicState2
2380 //-----------------------------------------------------------------------------
2381 class BasicState2 : public VertexAttribBindingBase
2382 {
2383 GLuint m_vao, m_vbo;
2384
Setup()2385 virtual long Setup()
2386 {
2387 glGenVertexArrays(1, &m_vao);
2388 glGenBuffers(1, &m_vbo);
2389 return NO_ERROR;
2390 }
2391
Cleanup()2392 virtual long Cleanup()
2393 {
2394 glDeleteVertexArrays(1, &m_vao);
2395 glDeleteBuffers(1, &m_vbo);
2396 return NO_ERROR;
2397 }
2398
Run()2399 virtual long Run()
2400 {
2401 GLint p;
2402 glBindVertexArray(m_vao);
2403 for (GLuint i = 0; i < 16; ++i)
2404 {
2405 glGetIntegeri_v(GL_VERTEX_BINDING_DIVISOR, i, &p);
2406 if (glGetError() != GL_NO_ERROR)
2407 {
2408 m_context.getTestContext().getLog()
2409 << tcu::TestLog::Message
2410 << "glGetIntegeri_v(GL_VERTEX_BINDING_DIVISOR, ...) command generates error."
2411 << tcu::TestLog::EndMessage;
2412 return ERROR;
2413 }
2414 if (p != 0)
2415 {
2416 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_DIVISOR(" << i
2417 << ") is " << p << " should be 0." << tcu::TestLog::EndMessage;
2418 return ERROR;
2419 }
2420 }
2421 glVertexBindingDivisor(1, 2);
2422 glGetIntegeri_v(GL_VERTEX_BINDING_DIVISOR, 1, &p);
2423 if (p != 2)
2424 {
2425 m_context.getTestContext().getLog()
2426 << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_DIVISOR(1) is %d should be 2."
2427 << tcu::TestLog::EndMessage;
2428 return ERROR;
2429 }
2430 return NO_ERROR;
2431 }
2432 };
2433
2434 class VertexAttribState : public deqp::GLWrapper
2435 {
2436 public:
2437 int array_enabled;
2438 int array_size;
2439 int array_stride;
2440 int array_type;
2441 int array_normalized;
2442 int array_integer;
2443 int array_long;
2444 int array_divisor;
2445 deUintptr array_pointer;
2446 int array_buffer_binding;
2447 int binding;
2448 int relative_offset;
2449 int index;
2450
VertexAttribState(int attribindex)2451 VertexAttribState(int attribindex)
2452 : array_enabled(0)
2453 , array_size(4)
2454 , array_stride(0)
2455 , array_type(GL_FLOAT)
2456 , array_normalized(0)
2457 , array_integer(0)
2458 , array_long(0)
2459 , array_divisor(0)
2460 , array_pointer(0)
2461 , array_buffer_binding(0)
2462 , binding(attribindex)
2463 , relative_offset(0)
2464 , index(attribindex)
2465 {
2466 }
2467
stateVerify()2468 bool stateVerify()
2469 {
2470 GLint p;
2471 bool status = true;
2472 glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &p);
2473 if (p != array_enabled)
2474 {
2475 m_context.getTestContext().getLog()
2476 << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_ENABLED(" << index << ") is " << p << " should be "
2477 << array_enabled << tcu::TestLog::EndMessage;
2478 status = false;
2479 }
2480 glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_SIZE, &p);
2481 if (p != array_size)
2482 {
2483 m_context.getTestContext().getLog()
2484 << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_SIZE(" << index << ") is " << p << " should be "
2485 << array_size << tcu::TestLog::EndMessage;
2486 status = false;
2487 }
2488 glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &p);
2489 if (p != array_stride)
2490 {
2491 m_context.getTestContext().getLog()
2492 << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_STRIDE(" << index << ") is " << p << " should be "
2493 << array_stride << tcu::TestLog::EndMessage;
2494 status = false;
2495 }
2496 glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_TYPE, &p);
2497 if (p != array_type)
2498 {
2499 m_context.getTestContext().getLog()
2500 << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_TYPE(" << index << ") is " << tcu::toHex(p)
2501 << " should be " << tcu::toHex(array_type) << tcu::TestLog::EndMessage;
2502 status = false;
2503 }
2504 glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &p);
2505 if (p != array_normalized)
2506 {
2507 m_context.getTestContext().getLog()
2508 << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED(" << index << ") is " << p
2509 << " should be " << array_normalized << tcu::TestLog::EndMessage;
2510 status = false;
2511 }
2512 glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_INTEGER, &p);
2513 if (p != array_integer)
2514 {
2515 m_context.getTestContext().getLog()
2516 << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_INTEGER(" << index << ") is " << p << " should be "
2517 << array_integer << tcu::TestLog::EndMessage;
2518 status = false;
2519 }
2520 glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_LONG, &p);
2521 if (p != array_long)
2522 {
2523 m_context.getTestContext().getLog()
2524 << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_LONG(" << index << ") is " << p << " should be "
2525 << array_long << tcu::TestLog::EndMessage;
2526 status = false;
2527 }
2528 glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, &p);
2529 if (p != array_divisor)
2530 {
2531 m_context.getTestContext().getLog()
2532 << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_DIVISOR(" << index << ") is " << p << " should be "
2533 << array_divisor << tcu::TestLog::EndMessage;
2534 status = false;
2535 }
2536 void* pp;
2537 glGetVertexAttribPointerv(index, GL_VERTEX_ATTRIB_ARRAY_POINTER, &pp);
2538 if (reinterpret_cast<deUintptr>(pp) != array_pointer)
2539 {
2540 m_context.getTestContext().getLog()
2541 << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_POINTER(" << index << ") is "
2542 << reinterpret_cast<deUintptr>(pp) << " should be " << array_pointer << tcu::TestLog::EndMessage;
2543 status = false;
2544 }
2545 glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &p);
2546 if (p != array_buffer_binding)
2547 {
2548 m_context.getTestContext().getLog()
2549 << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING(" << index << ") is " << p
2550 << " should be " << array_buffer_binding << tcu::TestLog::EndMessage;
2551 status = false;
2552 }
2553 glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_BINDING, &p);
2554 if (static_cast<GLint>(binding) != p)
2555 {
2556 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_BINDING(" << index
2557 << ") is " << p << " should be " << binding << tcu::TestLog::EndMessage;
2558 status = false;
2559 }
2560 glGetVertexAttribiv(index, GL_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
2561 if (p != relative_offset)
2562 {
2563 m_context.getTestContext().getLog()
2564 << tcu::TestLog::Message << "GL_VERTEX_ATTRIB_RELATIVE_OFFSET(" << index << ") is " << p
2565 << " should be " << relative_offset << tcu::TestLog::EndMessage;
2566 status = false;
2567 }
2568 return status;
2569 }
2570 };
2571
2572 class VertexBindingState : public deqp::GLWrapper
2573 {
2574 public:
2575 int buffer;
2576 long int offset;
2577 int stride;
2578 int divisor;
2579 int index;
2580
VertexBindingState(int bindingindex)2581 VertexBindingState(int bindingindex) : buffer(0), offset(0), stride(16), divisor(0), index(bindingindex)
2582 {
2583 }
2584
stateVerify()2585 bool stateVerify()
2586 {
2587 bool status = true;
2588 GLint p;
2589 glGetIntegeri_v(GL_VERTEX_BINDING_BUFFER, index, &p);
2590 if (p != buffer)
2591 {
2592 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_BUFFER(" << index
2593 << ") is " << p << " should be " << buffer << tcu::TestLog::EndMessage;
2594 status = false;
2595 }
2596 GLint64 p64;
2597 glGetInteger64i_v(GL_VERTEX_BINDING_OFFSET, index, &p64);
2598 if (p64 != offset)
2599 {
2600 m_context.getTestContext().getLog()
2601 << tcu::TestLog::Message << "GL_VERTEX_BINDING_OFFSET(" << index << ") is " << p64 << " should be "
2602 << offset << tcu::TestLog::EndMessage;
2603 status = false;
2604 }
2605 glGetIntegeri_v(GL_VERTEX_BINDING_STRIDE, index, &p);
2606 if (p != stride)
2607 {
2608 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_STRIDE(" << index
2609 << ") is " << p << " should be " << stride << tcu::TestLog::EndMessage;
2610 status = false;
2611 }
2612 glGetIntegeri_v(GL_VERTEX_BINDING_DIVISOR, index, &p);
2613 if (p != divisor)
2614 {
2615 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_VERTEX_BINDING_DIVISOR(" << index
2616 << ") is " << p << " should be " << divisor << tcu::TestLog::EndMessage;
2617 status = false;
2618 }
2619 return status;
2620 }
2621 };
2622
2623 //=============================================================================
2624 // 1.6 BasicState3
2625 //-----------------------------------------------------------------------------
2626 class BasicState3 : public VertexAttribBindingBase
2627 {
2628
2629 GLuint m_vao, m_vbo[3];
2630
Setup()2631 virtual long Setup()
2632 {
2633 glGenVertexArrays(1, &m_vao);
2634 glGenBuffers(3, m_vbo);
2635 return NO_ERROR;
2636 }
2637
Cleanup()2638 virtual long Cleanup()
2639 {
2640 glDeleteVertexArrays(1, &m_vao);
2641 glDeleteBuffers(3, m_vbo);
2642 return NO_ERROR;
2643 }
2644
Run()2645 virtual long Run()
2646 {
2647 bool status = true;
2648 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
2649 glBufferData(GL_ARRAY_BUFFER, 10000, NULL, GL_DYNAMIC_COPY);
2650 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
2651 glBufferData(GL_ARRAY_BUFFER, 10000, NULL, GL_DYNAMIC_COPY);
2652 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[2]);
2653 glBufferData(GL_ARRAY_BUFFER, 10000, NULL, GL_DYNAMIC_COPY);
2654 glBindBuffer(GL_ARRAY_BUFFER, 0);
2655
2656 GLint p;
2657 glGetIntegerv(GL_MAX_VERTEX_ATTRIB_BINDINGS, &p);
2658 if (p < 16)
2659 {
2660 m_context.getTestContext().getLog()
2661 << tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_BINDINGS is %d but must be at least 16."
2662 << tcu::TestLog::EndMessage;
2663 status = false;
2664 }
2665 glGetIntegerv(GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET, &p);
2666 if (p < 2047)
2667 {
2668 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET is "
2669 << p << " but must be at least 2047." << tcu::TestLog::EndMessage;
2670 status = false;
2671 }
2672 glGetIntegerv(GL_MAX_VERTEX_ATTRIB_STRIDE, &p);
2673 if (p < 2048)
2674 {
2675 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_MAX_VERTEX_ATTRIB_STRIDE is " << p
2676 << " but must be at least 2048." << tcu::TestLog::EndMessage;
2677 status = false;
2678 }
2679
2680 glBindVertexArray(m_vao);
2681
2682 glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &p);
2683 if (0 != p)
2684 {
2685 m_context.getTestContext().getLog() << tcu::TestLog::Message << "GL_ELEMENT_ARRAY_BUFFER_BINDING is " << p
2686 << " should be 0." << tcu::TestLog::EndMessage;
2687 status = false;
2688 }
2689 for (GLuint i = 0; i < 16; ++i)
2690 {
2691 VertexAttribState va(i);
2692 if (!va.stateVerify())
2693 status = false;
2694 }
2695 for (GLuint i = 0; i < 16; ++i)
2696 {
2697 VertexBindingState vb(i);
2698 if (!vb.stateVerify())
2699 status = false;
2700 }
2701 if (!status)
2702 {
2703 m_context.getTestContext().getLog()
2704 << tcu::TestLog::Message << "Default state check failed." << tcu::TestLog::EndMessage;
2705 status = false;
2706 }
2707
2708 VertexAttribState va0(0);
2709 va0.array_size = 2;
2710 va0.array_type = GL_BYTE;
2711 va0.array_normalized = 1;
2712 va0.relative_offset = 16;
2713 VertexBindingState vb0(0);
2714 glVertexAttribFormat(0, 2, GL_BYTE, GL_TRUE, 16);
2715 if (!va0.stateVerify() || !vb0.stateVerify())
2716 {
2717 m_context.getTestContext().getLog()
2718 << tcu::TestLog::Message << "glVertexAttribFormat state change check failed."
2719 << tcu::TestLog::EndMessage;
2720 status = false;
2721 }
2722
2723 VertexAttribState va2(2);
2724 va2.array_size = 3;
2725 va2.array_type = GL_DOUBLE;
2726 va2.array_long = 1;
2727 va2.relative_offset = 512;
2728 VertexBindingState vb2(2);
2729 glVertexAttribLFormat(2, 3, GL_DOUBLE, 512);
2730 if (!va2.stateVerify() || !vb2.stateVerify())
2731 {
2732 m_context.getTestContext().getLog()
2733 << tcu::TestLog::Message << "glVertexAttribIFormat state change check failed."
2734 << tcu::TestLog::EndMessage;
2735 status = false;
2736 }
2737
2738 va0.array_buffer_binding = m_vbo[0];
2739 vb0.buffer = m_vbo[0];
2740 vb0.offset = 2048;
2741 vb0.stride = 128;
2742 glBindVertexBuffer(0, m_vbo[0], 2048, 128);
2743 if (!va0.stateVerify() || !vb0.stateVerify())
2744 {
2745 m_context.getTestContext().getLog()
2746 << tcu::TestLog::Message << "glBindVertexBuffer state change check failed." << tcu::TestLog::EndMessage;
2747 status = false;
2748 }
2749
2750 va2.array_buffer_binding = m_vbo[2];
2751 vb2.buffer = m_vbo[2];
2752 vb2.offset = 64;
2753 vb2.stride = 256;
2754 glBindVertexBuffer(2, m_vbo[2], 64, 256);
2755 if (!va2.stateVerify() || !vb2.stateVerify())
2756 {
2757 m_context.getTestContext().getLog()
2758 << tcu::TestLog::Message << "glBindVertexBuffer state change check failed." << tcu::TestLog::EndMessage;
2759 status = false;
2760 }
2761
2762 glVertexAttribBinding(2, 0);
2763 va2.binding = 0;
2764 va2.array_buffer_binding = m_vbo[0];
2765 if (!va0.stateVerify() || !vb0.stateVerify() || !va2.stateVerify() || !vb2.stateVerify())
2766 {
2767 m_context.getTestContext().getLog()
2768 << tcu::TestLog::Message << "glVertexAttribBinding state change check failed."
2769 << tcu::TestLog::EndMessage;
2770 status = false;
2771 }
2772
2773 VertexAttribState va15(15);
2774 VertexBindingState vb15(15);
2775 glVertexAttribBinding(0, 15);
2776 va0.binding = 15;
2777 va0.array_buffer_binding = 0;
2778 if (!va0.stateVerify() || !vb0.stateVerify() || !va15.stateVerify() || !vb15.stateVerify())
2779 {
2780 m_context.getTestContext().getLog()
2781 << tcu::TestLog::Message << "glVertexAttribBinding state change check failed."
2782 << tcu::TestLog::EndMessage;
2783 status = false;
2784 }
2785
2786 glBindVertexBuffer(15, m_vbo[1], 16, 32);
2787 va0.array_buffer_binding = m_vbo[1];
2788 va15.array_buffer_binding = m_vbo[1];
2789 vb15.buffer = m_vbo[1];
2790 vb15.offset = 16;
2791 vb15.stride = 32;
2792 if (!va0.stateVerify() || !vb0.stateVerify() || !va15.stateVerify() || !vb15.stateVerify())
2793 {
2794 m_context.getTestContext().getLog()
2795 << tcu::TestLog::Message << "glBindVertexBuffer state change check failed." << tcu::TestLog::EndMessage;
2796 status = false;
2797 }
2798
2799 glVertexAttribLFormat(15, 1, GL_DOUBLE, 1024);
2800 va15.array_size = 1;
2801 va15.array_long = 1;
2802 va15.array_type = GL_DOUBLE;
2803 va15.relative_offset = 1024;
2804 if (!va0.stateVerify() || !vb0.stateVerify() || !va2.stateVerify() || !vb2.stateVerify() ||
2805 !va15.stateVerify() || !vb15.stateVerify())
2806 {
2807 m_context.getTestContext().getLog()
2808 << tcu::TestLog::Message << "glVertexAttribFormat state change check failed."
2809 << tcu::TestLog::EndMessage;
2810 status = false;
2811 }
2812
2813 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[2]);
2814 glVertexAttribPointer(0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 8, (void*)640);
2815 glBindBuffer(GL_ARRAY_BUFFER, 0);
2816 va0.array_size = 4;
2817 va0.array_type = GL_UNSIGNED_BYTE;
2818 va0.array_stride = 8;
2819 va0.array_pointer = 640;
2820 va0.relative_offset = 0;
2821 va0.array_normalized = 0;
2822 va0.binding = 0;
2823 va0.array_buffer_binding = m_vbo[2];
2824 vb0.buffer = m_vbo[2];
2825 vb0.offset = 640;
2826 vb0.stride = 8;
2827 va2.array_buffer_binding = m_vbo[2];
2828 if (!va0.stateVerify() || !vb0.stateVerify() || !va2.stateVerify() || !vb2.stateVerify() ||
2829 !va15.stateVerify() || !vb15.stateVerify())
2830 {
2831 m_context.getTestContext().getLog()
2832 << tcu::TestLog::Message << "glVertexAttribPointer state change check failed."
2833 << tcu::TestLog::EndMessage;
2834 status = false;
2835 }
2836
2837 glBindVertexBuffer(0, m_vbo[1], 80, 24);
2838 vb0.buffer = m_vbo[1];
2839 vb0.offset = 80;
2840 vb0.stride = 24;
2841 va2.array_buffer_binding = m_vbo[1];
2842 va0.array_buffer_binding = m_vbo[1];
2843 if (!va0.stateVerify() || !vb0.stateVerify() || !va2.stateVerify() || !vb2.stateVerify() ||
2844 !va15.stateVerify() || !vb15.stateVerify())
2845 {
2846 m_context.getTestContext().getLog()
2847 << tcu::TestLog::Message << "glBindVertexBuffer state change check failed." << tcu::TestLog::EndMessage;
2848 status = false;
2849 }
2850
2851 if (status)
2852 return NO_ERROR;
2853 else
2854 return ERROR;
2855 }
2856 };
2857
2858 //=============================================================================
2859 // 1.7 BasicState4
2860 //-----------------------------------------------------------------------------
2861 class BasicState4 : public VertexAttribBindingBase
2862 {
2863 GLuint m_vao;
2864
Setup()2865 virtual long Setup()
2866 {
2867 glGenVertexArrays(1, &m_vao);
2868 return NO_ERROR;
2869 }
2870
Cleanup()2871 virtual long Cleanup()
2872 {
2873 glDeleteVertexArrays(1, &m_vao);
2874 return NO_ERROR;
2875 }
2876
Run()2877 virtual long Run()
2878 {
2879 bool status = true;
2880 glBindVertexArray(m_vao);
2881
2882 for (GLuint i = 0; i < 16; ++i)
2883 {
2884 VertexAttribState va(i);
2885 VertexBindingState vb(i);
2886 glVertexAttribDivisor(i, i + 7);
2887 va.array_divisor = i + 7;
2888 vb.divisor = i + 7;
2889 if (!va.stateVerify() || !vb.stateVerify())
2890 {
2891 m_context.getTestContext().getLog()
2892 << tcu::TestLog::Message << "glVertexAttribDivisor state change check failed."
2893 << tcu::TestLog::EndMessage;
2894 status = false;
2895 }
2896 }
2897 for (GLuint i = 0; i < 16; ++i)
2898 {
2899 VertexAttribState va(i);
2900 VertexBindingState vb(i);
2901 glVertexBindingDivisor(i, i);
2902 va.array_divisor = i;
2903 vb.divisor = i;
2904 if (!va.stateVerify() || !vb.stateVerify())
2905 {
2906 m_context.getTestContext().getLog()
2907 << tcu::TestLog::Message << "glVertexBindingDivisor state change check failed."
2908 << tcu::TestLog::EndMessage;
2909 status = false;
2910 }
2911 }
2912
2913 glVertexAttribBinding(2, 5);
2914 VertexAttribState va5(5);
2915 va5.array_divisor = 5;
2916 VertexBindingState vb5(5);
2917 vb5.divisor = 5;
2918 VertexAttribState va2(2);
2919 va2.array_divisor = 5;
2920 VertexBindingState vb2(2);
2921 vb2.divisor = 2;
2922 va2.binding = 5;
2923 if (!va5.stateVerify() || !vb5.stateVerify() || !va2.stateVerify() || !vb2.stateVerify())
2924 {
2925 m_context.getTestContext().getLog()
2926 << tcu::TestLog::Message << "glVertexAttribBinding state change check failed."
2927 << tcu::TestLog::EndMessage;
2928 status = false;
2929 }
2930
2931 glVertexAttribDivisor(2, 23);
2932 va2.binding = 2;
2933 va2.array_divisor = 23;
2934 vb2.divisor = 23;
2935 if (!va5.stateVerify() || !vb5.stateVerify() || !va2.stateVerify() || !vb2.stateVerify())
2936 {
2937 m_context.getTestContext().getLog()
2938 << tcu::TestLog::Message << "glVertexAttribDivisor state change check failed."
2939 << tcu::TestLog::EndMessage;
2940 status = false;
2941 }
2942
2943 if (status)
2944 return NO_ERROR;
2945 else
2946 return ERROR;
2947 }
2948 };
2949
2950 //=============================================================================
2951 // 2.1 AdvancedBindingUpdate
2952 //-----------------------------------------------------------------------------
2953 class AdvancedBindingUpdate : public VertexAttribBindingBase
2954 {
2955 GLuint m_vao[2], m_vbo[2], m_ebo[2], m_vsp, m_fsp, m_ppo;
2956
Setup()2957 virtual long Setup()
2958 {
2959 glGenVertexArrays(2, m_vao);
2960 glGenBuffers(2, m_vbo);
2961 glGenBuffers(2, m_ebo);
2962 m_vsp = m_fsp = 0;
2963 glGenProgramPipelines(1, &m_ppo);
2964 return NO_ERROR;
2965 }
2966
Cleanup()2967 virtual long Cleanup()
2968 {
2969 glDeleteVertexArrays(2, m_vao);
2970 glDeleteBuffers(2, m_vbo);
2971 glDeleteBuffers(2, m_ebo);
2972 glDeleteProgram(m_vsp);
2973 glDeleteProgram(m_fsp);
2974 glDeleteProgramPipelines(1, &m_ppo);
2975 return NO_ERROR;
2976 }
2977
Run()2978 virtual long Run()
2979 {
2980 const char* const glsl_vs =
2981 "#version 430 core" NL "layout(location = 0) in vec4 vs_in_position;" NL
2982 "layout(location = 1) in vec2 vs_in_color_rg;" NL "layout(location = 2) in float vs_in_color_b;" NL
2983 "layout(location = 3) in dvec3 vs_in_data0;" NL "layout(location = 4) in ivec2 vs_in_data1;" NL
2984 "out StageData {" NL " vec2 color_rg;" NL " float color_b;" NL " dvec3 data0;" NL " ivec2 data1;" NL
2985 "} vs_out;" NL "out gl_PerVertex {" NL " vec4 gl_Position;" NL "};" NL "void main() {" NL
2986 " vs_out.data1 = vs_in_data1;" NL " vs_out.data0 = vs_in_data0;" NL " vs_out.color_b = vs_in_color_b;" NL
2987 " vs_out.color_rg = vs_in_color_rg;" NL " gl_Position = vs_in_position;" NL "}";
2988 const char* const glsl_fs = "#version 430 core" NL "in StageData {" NL " vec2 color_rg;" NL
2989 " float color_b;" NL " flat dvec3 data0;" NL " flat ivec2 data1;" NL
2990 "} fs_in;" NL "layout(location = 0) out vec4 fs_out_color;" NL
2991 "uniform dvec3 g_expected_data0;" NL "uniform ivec2 g_expected_data1;" NL
2992 "void main() {" NL " fs_out_color = vec4(fs_in.color_rg, fs_in.color_b, 1);" NL
2993 " if (fs_in.data0 != g_expected_data0) fs_out_color = vec4(1);" NL
2994 " if (fs_in.data1 != g_expected_data1) fs_out_color = vec4(1);" NL "}";
2995 m_vsp = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);
2996 m_fsp = glCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &glsl_fs);
2997 if (!CheckProgram(m_vsp) || !CheckProgram(m_fsp))
2998 return ERROR;
2999
3000 glUseProgramStages(m_ppo, GL_VERTEX_SHADER_BIT, m_vsp);
3001 glUseProgramStages(m_ppo, GL_FRAGMENT_SHADER_BIT, m_fsp);
3002
3003 const GLsizei kStride[2] = { 52, 62 };
3004 const GLintptr kOffset[2] = { 0, 8 };
3005 /* Workaround for alignment issue that may result in bus error on some platforms */
3006 union {
3007 double d[3];
3008 char c[3 * sizeof(double)];
3009 } u;
3010
3011 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[0]);
3012 {
3013 glBufferData(GL_ARRAY_BUFFER, kOffset[0] + 4 * kStride[0], NULL, GL_STATIC_DRAW);
3014 GLubyte* ptr = static_cast<GLubyte*>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
3015
3016 *reinterpret_cast<Vec2*>(&ptr[kOffset[0] + 0 * kStride[0]]) = Vec2(-1.0f, -1.0f);
3017 *reinterpret_cast<Vec2*>(&ptr[kOffset[0] + 1 * kStride[0]]) = Vec2(1.0f, -1.0f);
3018 *reinterpret_cast<Vec2*>(&ptr[kOffset[0] + 2 * kStride[0]]) = Vec2(1.0f, 1.0f);
3019 *reinterpret_cast<Vec2*>(&ptr[kOffset[0] + 3 * kStride[0]]) = Vec2(-1.0f, 1.0f);
3020
3021 for (int i = 0; i < 4; ++i)
3022 {
3023 *reinterpret_cast<Vec2*>(&ptr[kOffset[0] + 8 + i * kStride[0]]) = Vec2(0.0f, 1.0f);
3024 *reinterpret_cast<float*>(&ptr[kOffset[0] + 16 + i * kStride[0]]) = 0.0f;
3025 //*reinterpret_cast<DVec3 *>(&ptr[kOffset[0] + 20 + i * kStride[0]]) = DVec3(1.0, 2.0, 3.0);
3026
3027 memcpy(u.d, DVec3(1.0, 2.0, 3.0).m_data, 3 * sizeof(double));
3028 memcpy(&ptr[kOffset[0] + 20 + i * kStride[0]], u.c, 3 * sizeof(double));
3029 *reinterpret_cast<IVec2*>(&ptr[kOffset[0] + 44 + i * kStride[0]]) = IVec2(1, 2);
3030 }
3031 glUnmapBuffer(GL_ARRAY_BUFFER);
3032 }
3033 glBindBuffer(GL_ARRAY_BUFFER, m_vbo[1]);
3034 {
3035 glBufferData(GL_ARRAY_BUFFER, kOffset[1] + 4 * kStride[1], NULL, GL_STATIC_DRAW);
3036 GLubyte* ptr = static_cast<GLubyte*>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
3037
3038 *reinterpret_cast<Vec2*>(&ptr[kOffset[1] + 0 * kStride[1]]) = Vec2(-1.0f, 1.0f);
3039 *reinterpret_cast<Vec2*>(&ptr[kOffset[1] + 1 * kStride[1]]) = Vec2(1.0f, 1.0f);
3040 *reinterpret_cast<Vec2*>(&ptr[kOffset[1] + 2 * kStride[1]]) = Vec2(1.0f, -1.0f);
3041 *reinterpret_cast<Vec2*>(&ptr[kOffset[1] + 3 * kStride[1]]) = Vec2(-1.0f, -1.0f);
3042
3043 for (int i = 0; i < 4; ++i)
3044 {
3045 *reinterpret_cast<Vec2*>(&ptr[kOffset[1] + 8 + i * kStride[1]]) = Vec2(0.0f, 0.0f);
3046 *reinterpret_cast<float*>(&ptr[kOffset[1] + 16 + i * kStride[1]]) = 1.0f;
3047 //*reinterpret_cast<DVec3 *>(&ptr[kOffset[1] + 20 + i * kStride[1]]) = DVec3(4.0, 5.0, 6.0);
3048
3049 memcpy(u.d, DVec3(4.0, 5.0, 6.0).m_data, 3 * sizeof(double));
3050 memcpy(&ptr[kOffset[1] + 20 + i * kStride[1]], u.c, 3 * sizeof(double));
3051 *reinterpret_cast<IVec2*>(&ptr[kOffset[1] + 44 + i * kStride[1]]) = IVec2(3, 4);
3052 }
3053 glUnmapBuffer(GL_ARRAY_BUFFER);
3054 }
3055 glBindBuffer(GL_ARRAY_BUFFER, 0);
3056
3057 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[0]);
3058 {
3059 GLushort data[4] = { 0, 1, 3, 2 };
3060 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
3061 }
3062 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[1]);
3063 {
3064 GLuint data[4] = { 3, 2, 0, 1 };
3065 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
3066 }
3067 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3068
3069 glBindVertexArray(m_vao[0]);
3070 glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
3071 glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, 8);
3072 glVertexAttribFormat(2, 1, GL_FLOAT, GL_FALSE, 16);
3073 glVertexAttribLFormat(3, 3, GL_DOUBLE, 20);
3074 glVertexAttribIFormat(4, 2, GL_INT, 44);
3075
3076 for (GLuint i = 0; i < 5; ++i)
3077 {
3078 glVertexAttribBinding(i, 0);
3079 glEnableVertexAttribArray(i);
3080 }
3081 glBindVertexArray(m_vao[1]);
3082 glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
3083 glVertexAttribFormat(1, 2, GL_FLOAT, GL_FALSE, 8);
3084 glVertexAttribFormat(2, 1, GL_FLOAT, GL_FALSE, 16);
3085 glVertexAttribLFormat(3, 3, GL_DOUBLE, 20);
3086 glVertexAttribIFormat(4, 2, GL_INT, 44);
3087 glVertexAttribBinding(0, 1);
3088 glVertexAttribBinding(1, 8);
3089 glVertexAttribBinding(2, 1);
3090 glVertexAttribBinding(3, 1);
3091 glVertexAttribBinding(4, 8);
3092 glEnableVertexAttribArray(0);
3093 glEnableVertexAttribArray(1);
3094 glEnableVertexAttribArray(2);
3095 glEnableVertexAttribArray(3);
3096 glEnableVertexAttribArray(4);
3097 glBindVertexBuffer(1, m_vbo[1], kOffset[1], kStride[1]);
3098 glBindVertexBuffer(8, m_vbo[0], kOffset[0], kStride[0]);
3099 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[1]);
3100 glBindVertexArray(0);
3101
3102 glClear(GL_COLOR_BUFFER_BIT);
3103 glBindProgramPipeline(m_ppo);
3104 glBindVertexArray(m_vao[0]);
3105
3106 glProgramUniform3d(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data0"), 1.0, 2.0, 3.0);
3107 glProgramUniform2i(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data1"), 1, 2);
3108
3109 glBindVertexBuffer(0, m_vbo[0], kOffset[0], kStride[0]);
3110 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[0]);
3111 glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1, 0, 0);
3112
3113 bool status = true;
3114 std::vector<Vec3> fb(getWindowWidth() * getWindowHeight());
3115 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3116 if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 1, 0)))
3117 status = false;
3118 if (!status)
3119 return ERROR;
3120
3121 glProgramUniform3d(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data0"), 4.0, 5.0, 6.0);
3122 glProgramUniform2i(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data1"), 3, 4);
3123
3124 glBindVertexBuffer(0, m_vbo[1], kOffset[1], kStride[1]);
3125 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[1]);
3126 glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0, 1, 0, 0);
3127
3128 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3129 if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 0, 1)))
3130 status = false;
3131 if (!status)
3132 return ERROR;
3133
3134 glBindVertexBuffer(0, 0, 0, 0);
3135
3136 glProgramUniform3d(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data0"), 1.0, 2.0, 3.0);
3137 glProgramUniform2i(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data1"), 1, 2);
3138
3139 for (GLuint i = 0; i < 5; ++i)
3140 glVertexAttribBinding(i, 15);
3141 glBindVertexBuffer(15, m_vbo[0], kOffset[0], kStride[0]);
3142 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[0]);
3143 glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1, 0, 0);
3144
3145 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3146 if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 1, 0)))
3147 status = false;
3148 if (!status)
3149 return ERROR;
3150
3151 glBindVertexBuffer(15, 0, 0, 0);
3152
3153 glProgramUniform3d(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data0"), 1.0, 2.0, 3.0);
3154 glProgramUniform2i(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data1"), 3, 4);
3155
3156 glBindVertexBuffer(7, m_vbo[0], kOffset[0], kStride[0]);
3157 glBindVertexBuffer(12, m_vbo[1], kOffset[1], kStride[1]);
3158 glVertexAttribBinding(0, 7);
3159 glVertexAttribBinding(1, 12);
3160 glVertexAttribBinding(2, 12);
3161 glVertexAttribBinding(3, 7);
3162 glVertexAttribBinding(4, 12);
3163 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo[0]);
3164 glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1, 0, 0);
3165
3166 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3167 if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 0, 1)))
3168 status = false;
3169 if (!status)
3170 return ERROR;
3171
3172 glClear(GL_COLOR_BUFFER_BIT);
3173 glProgramUniform2i(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data1"), 0, 0);
3174 glDisableVertexAttribArray(4);
3175 glVertexAttribI4i(4, 0, 0, 0, 0);
3176 glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, 0, 1, 0, 0);
3177
3178 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3179 if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 0, 1)))
3180 status = false;
3181 if (!status)
3182 return ERROR;
3183
3184 glProgramUniform3d(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data0"), 4.0, 5.0, 6.0);
3185 glProgramUniform2i(m_fsp, glGetUniformLocation(m_fsp, "g_expected_data1"), 1, 2);
3186
3187 glBindVertexArray(m_vao[1]);
3188 glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0, 1, 0, 0);
3189
3190 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3191 if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0.0f, 1.0f, 1.0f)))
3192 status = false;
3193 if (!status)
3194 return ERROR;
3195
3196 return NO_ERROR;
3197 }
3198 };
3199
3200 //=============================================================================
3201 // 2.2 AdvancedInstancing
3202 //-----------------------------------------------------------------------------
3203 class AdvancedInstancing : public VertexAttribBindingBase
3204 {
3205 GLuint m_pipeline;
3206 GLuint m_vsp, m_fsp;
3207 GLuint m_vertex_array[2];
3208 GLuint m_vertex_buffer;
3209 GLuint m_index_buffer;
3210 GLuint m_object_id_buffer;
3211 GLuint m_transform_texture, m_transform_buffer;
3212
Setup()3213 virtual long Setup()
3214 {
3215 glGenProgramPipelines(1, &m_pipeline);
3216 m_vsp = m_fsp = 0;
3217 glGenVertexArrays(2, m_vertex_array);
3218 glGenBuffers(1, &m_vertex_buffer);
3219 glGenBuffers(1, &m_index_buffer);
3220 glGenBuffers(1, &m_object_id_buffer);
3221 glGenBuffers(1, &m_transform_buffer);
3222 glGenTextures(1, &m_transform_texture);
3223 return NO_ERROR;
3224 }
3225
Cleanup()3226 virtual long Cleanup()
3227 {
3228 glDeleteProgramPipelines(1, &m_pipeline);
3229 glDeleteProgram(m_vsp);
3230 glDeleteProgram(m_fsp);
3231 glDeleteVertexArrays(2, m_vertex_array);
3232 glDeleteBuffers(1, &m_vertex_buffer);
3233 glDeleteBuffers(1, &m_index_buffer);
3234 glDeleteBuffers(1, &m_object_id_buffer);
3235 glDeleteBuffers(1, &m_transform_buffer);
3236 glDeleteTextures(1, &m_transform_texture);
3237 return NO_ERROR;
3238 }
3239
Run()3240 virtual long Run()
3241 {
3242 const char* const glsl_ver = "#version 430 core\n";
3243 const char* const glsl =
3244 NL "#if defined(VS_PASS_THROUGH)" NL "layout(location = 0) in vec4 vs_in_position;" NL
3245 "layout(location = 1) in vec3 vs_in_normal;" NL "layout(location = 2) in int vs_in_object_id;" NL
3246 "out StageData {" NL " float f;" NL " vec3 normal;" NL " int object_id;" NL "} vs_out;" NL
3247 "out gl_PerVertex {" NL " vec4 gl_Position;" NL "};" NL
3248 "layout(binding = 0) uniform samplerBuffer g_transform_buffer;" NL "mat4 GetTransformMatrix(int id) {" NL
3249 " return mat4(texelFetch(g_transform_buffer, id * 4)," NL
3250 " texelFetch(g_transform_buffer, id * 4 + 1)," NL
3251 " texelFetch(g_transform_buffer, id * 4 + 2)," NL
3252 " texelFetch(g_transform_buffer, id * 4 + 3));" NL "}" NL "void main() {" NL
3253 " gl_Position = GetTransformMatrix(vs_in_object_id) * vs_in_position;" NL " vs_out.f = 123.0;" NL
3254 " vs_out.normal = vs_in_normal;" NL " vs_out.object_id = vs_in_object_id;" NL "}" NL
3255 "#elif defined(FS_SOLID_COLOR)" NL "in StageData {" NL " float f;" NL " vec3 normal;" NL
3256 " flat int object_id;" NL "} fs_in;" NL "layout(location = 0) out vec4 g_color;" NL "void main() {" NL
3257 " if (fs_in.object_id == 0) g_color = vec4(1, 0, 0, 1);" NL
3258 " else if (fs_in.object_id == 1) g_color = vec4(0, 1, 0, 1);" NL
3259 " else if (fs_in.object_id == 2) g_color = vec4(0, 0, 1, 1);" NL
3260 " else if (fs_in.object_id == 3) g_color = vec4(1, 1, 0, 1);" NL "}" NL "#endif";
3261 /* VS_PASS_THROUGH */
3262 {
3263 const char* const src[] = { glsl_ver, "#define VS_PASS_THROUGH\n", glsl };
3264 m_vsp = glCreateShaderProgramv(GL_VERTEX_SHADER, sizeof(src) / sizeof(src[0]), src);
3265 }
3266 /* FS_SOLID_COLOR */
3267 {
3268 const char* const src[] = { glsl_ver, "#define FS_SOLID_COLOR\n", glsl };
3269 m_fsp = glCreateShaderProgramv(GL_FRAGMENT_SHADER, sizeof(src) / sizeof(src[0]), src);
3270 }
3271 if (!CheckProgram(m_vsp))
3272 return ERROR;
3273 if (!CheckProgram(m_fsp))
3274 return ERROR;
3275
3276 glUseProgramStages(m_pipeline, GL_VERTEX_SHADER_BIT, m_vsp);
3277 glUseProgramStages(m_pipeline, GL_FRAGMENT_SHADER_BIT, m_fsp);
3278
3279 {
3280 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,
3281 1.0f, 0.0f, 0.0f, 1.5f, 1.5f, 1.0f, 0.0f, 0.0f, -1.5f, -0.5f, 0.0f, 1.0f,
3282 0.0f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, -1.5f, 1.5f, 0.0f, 1.0f, 0.0f, 0.5f,
3283 1.5f, 0.0f, 1.0f, 0.0f, -1.5f, -1.5f, 0.0f, 0.0f, 1.0f, 0.5f, -1.5f, 0.0f,
3284 0.0f, 1.0f, -1.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f,
3285 -0.5f, -1.5f, 1.0f, 1.0f, 0.0f, 1.5f, -1.5f, 1.0f, 1.0f, 0.0f, -0.5f, 0.5f,
3286 1.0f, 1.0f, 0.0f, 1.5f, 0.5f, 1.0f, 1.0f, 0.0f };
3287 glBindBuffer(GL_ARRAY_BUFFER, m_vertex_buffer);
3288 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
3289 glBindBuffer(GL_ARRAY_BUFFER, 0);
3290 }
3291 {
3292 const unsigned int data[] = { 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 };
3293 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer);
3294 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
3295 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
3296 }
3297 {
3298 const int data[] = { 0, 1, 2, 3 };
3299 glBindBuffer(GL_ARRAY_BUFFER, m_object_id_buffer);
3300 glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
3301 glBindBuffer(GL_ARRAY_BUFFER, 0);
3302 }
3303 glBindVertexArray(m_vertex_array[0]);
3304 glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
3305 glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 8);
3306 glVertexAttribIFormat(2, 1, GL_INT, 0);
3307 glEnableVertexAttribArray(0);
3308 glEnableVertexAttribArray(1);
3309 glEnableVertexAttribArray(2);
3310 glVertexAttribBinding(1, 0);
3311 glBindVertexBuffer(0, m_vertex_buffer, 0, 20);
3312 glBindVertexBuffer(2, m_object_id_buffer, 0, 4);
3313 glVertexBindingDivisor(2, 1);
3314 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer);
3315 glBindVertexArray(m_vertex_array[1]);
3316 glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 0);
3317 glVertexAttribFormat(1, 3, GL_FLOAT, GL_FALSE, 0);
3318 glVertexAttribIFormat(2, 1, GL_INT, 0);
3319 glEnableVertexAttribArray(0);
3320 glEnableVertexAttribArray(1);
3321 glEnableVertexAttribArray(2);
3322 glVertexAttribBinding(2, 13);
3323 glVertexAttribBinding(1, 14);
3324 glVertexAttribBinding(0, 15);
3325 glBindVertexBuffer(15, m_vertex_buffer, 0, 20);
3326 glBindVertexBuffer(14, m_vertex_buffer, 8, 20);
3327 glBindVertexBuffer(13, m_object_id_buffer, 0, 4);
3328 glVertexBindingDivisor(13, 1);
3329 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_index_buffer);
3330 glBindVertexArray(0);
3331
3332 {
3333 const Mat4 data[] = { Translation(-0.5f, -0.5f, 0.0f), Translation(0.5f, -0.5f, 0.0f),
3334 Translation(0.5f, 0.5f, 0.0f), Translation(-0.5f, 0.5f, 0.0f) };
3335 glBindBuffer(GL_TEXTURE_BUFFER, m_transform_buffer);
3336 glBufferData(GL_TEXTURE_BUFFER, sizeof(data), &data, GL_DYNAMIC_DRAW);
3337 glBindBuffer(GL_TEXTURE_BUFFER, 0);
3338 }
3339 glBindTexture(GL_TEXTURE_BUFFER, m_transform_texture);
3340 glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_transform_buffer);
3341 glBindTexture(GL_TEXTURE_BUFFER, 0);
3342
3343 glClear(GL_COLOR_BUFFER_BIT);
3344 glBindProgramPipeline(m_pipeline);
3345 glActiveTexture(GL_TEXTURE0);
3346 glBindTexture(GL_TEXTURE_BUFFER, m_transform_texture);
3347 glBindVertexArray(m_vertex_array[0]);
3348
3349 std::vector<Vec3> fb(getWindowWidth() * getWindowHeight());
3350 bool status = true;
3351
3352 glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0, 1, 0, 0);
3353 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3354 if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(1, 0, 0)))
3355 status = false;
3356 if (!status)
3357 return ERROR;
3358
3359 glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT,
3360 (void*)(4 * sizeof(unsigned int)), 1, 4, 1);
3361 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3362 if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 1, 0)))
3363 status = false;
3364 if (!status)
3365 return ERROR;
3366
3367 glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT,
3368 (void*)(8 * sizeof(unsigned int)), 1, 8, 2);
3369 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3370 if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 0, 1)))
3371 status = false;
3372 if (!status)
3373 return ERROR;
3374
3375 glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT,
3376 (void*)(12 * sizeof(unsigned int)), 1, 12, 3);
3377 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3378 if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(1, 1, 0)))
3379 status = false;
3380 if (!status)
3381 return ERROR;
3382
3383 glBindVertexArray(m_vertex_array[1]);
3384
3385 glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT,
3386 (void*)(8 * sizeof(unsigned int)), 1, 8, 2);
3387 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3388 if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 0, 1)))
3389 status = false;
3390 if (!status)
3391 return ERROR;
3392
3393 glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0, 1, 0, 0);
3394 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3395 if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(1, 0, 0)))
3396 status = false;
3397 if (!status)
3398 return ERROR;
3399
3400 glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT,
3401 (void*)(4 * sizeof(unsigned int)), 1, 4, 1);
3402 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3403 if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(0, 1, 0)))
3404 status = false;
3405 if (!status)
3406 return ERROR;
3407
3408 glDrawElementsInstancedBaseVertexBaseInstance(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT,
3409 (void*)(12 * sizeof(unsigned int)), 1, 12, 3);
3410 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGB, GL_FLOAT, &fb[0][0]);
3411 if (!CheckRectColor(fb, getWindowWidth(), 0, 0, getWindowWidth(), getWindowHeight(), Vec3(1, 1, 0)))
3412 status = false;
3413 if (!status)
3414 return ERROR;
3415
3416 return NO_ERROR;
3417 }
3418 };
3419
3420 //=============================================================================
3421 // 2.3 AdvancedIterations
3422 //-----------------------------------------------------------------------------
3423 class AdvancedIterations : public VertexAttribBindingBase
3424 {
3425 GLuint m_po, m_vao[2], m_xfo[2], m_buffer[2];
3426
Setup()3427 virtual long Setup()
3428 {
3429 m_po = 0;
3430 glGenVertexArrays(2, m_vao);
3431 glGenTransformFeedbacks(2, m_xfo);
3432 glGenBuffers(2, m_buffer);
3433 return NO_ERROR;
3434 }
3435
Cleanup()3436 virtual long Cleanup()
3437 {
3438 glDisable(GL_RASTERIZER_DISCARD);
3439 glUseProgram(0);
3440 glDeleteProgram(m_po);
3441 glDeleteVertexArrays(2, m_vao);
3442 glDeleteTransformFeedbacks(2, m_xfo);
3443 glDeleteBuffers(2, m_buffer);
3444 return NO_ERROR;
3445 }
3446
Run()3447 virtual long Run()
3448 {
3449 const char* const glsl_vs =
3450 "#version 430 core" NL "in ivec4 vs_in_data;" NL "out StageData {" NL " ivec4 data;" NL "} vs_out;" NL
3451 "void main() {" NL " vs_out.data = vs_in_data + 1;" NL "}";
3452
3453 m_po = glCreateProgram();
3454 {
3455 const GLuint sh = glCreateShader(GL_VERTEX_SHADER);
3456 glShaderSource(sh, 1, &glsl_vs, NULL);
3457 glCompileShader(sh);
3458 glAttachShader(m_po, sh);
3459 glDeleteShader(sh);
3460 }
3461 if (!RelinkProgram(1))
3462 return ERROR;
3463
3464 glBindBuffer(GL_ARRAY_BUFFER, m_buffer[0]);
3465 IVec4 zero(0);
3466 glBufferData(GL_ARRAY_BUFFER, 16, &zero, GL_STATIC_DRAW);
3467 glBindBuffer(GL_ARRAY_BUFFER, 0);
3468
3469 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer[1]);
3470 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, &zero, GL_DYNAMIC_READ);
3471 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
3472
3473 glBindVertexArray(m_vao[0]);
3474 glVertexAttribIFormat(1, 4, GL_INT, 0);
3475 glEnableVertexAttribArray(1);
3476 glBindVertexBuffer(1, m_buffer[0], 0, 16);
3477 glBindVertexArray(m_vao[1]);
3478 glVertexAttribIFormat(1, 4, GL_INT, 0);
3479 glEnableVertexAttribArray(1);
3480 glBindVertexBuffer(1, m_buffer[1], 0, 16);
3481 glBindVertexArray(0);
3482
3483 glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfo[0]);
3484 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer[1]);
3485 glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfo[1]);
3486 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer[0]);
3487 glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
3488
3489 glEnable(GL_RASTERIZER_DISCARD);
3490 glUseProgram(m_po);
3491
3492 for (int i = 0; i < 10; ++i)
3493 {
3494 glBindVertexArray(m_vao[i % 2]);
3495 glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfo[i % 2]);
3496 glBeginTransformFeedback(GL_POINTS);
3497 glDrawArrays(GL_POINTS, 0, 1);
3498 glEndTransformFeedback();
3499 }
3500 {
3501 IVec4 data;
3502 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer[0]);
3503 glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 16, &data[0]);
3504 if (!IsEqual(data, IVec4(10)))
3505 {
3506 m_context.getTestContext().getLog()
3507 << tcu::TestLog::Message << "Data is: " << data[0] << " " << data[1] << " " << data[2] << " "
3508 << data[3] << ", data should be: 10 10 10 10." << tcu::TestLog::EndMessage;
3509 return ERROR;
3510 }
3511 }
3512
3513 if (!RelinkProgram(5))
3514 return ERROR;
3515
3516 glBindVertexArray(m_vao[0]);
3517 glDisableVertexAttribArray(1);
3518 glBindVertexBuffer(1, 0, 0, 0);
3519 glVertexAttribIFormat(5, 4, GL_INT, 0);
3520 glEnableVertexAttribArray(5);
3521 glBindVertexBuffer(5, m_buffer[0], 0, 16);
3522 glBindVertexArray(m_vao[1]);
3523 glDisableVertexAttribArray(1);
3524 glBindVertexBuffer(1, 0, 0, 0);
3525 glVertexAttribIFormat(5, 4, GL_INT, 0);
3526 glEnableVertexAttribArray(5);
3527 glBindVertexBuffer(7, m_buffer[1], 0, 16);
3528 glVertexAttribBinding(5, 7);
3529 glBindVertexArray(0);
3530
3531 for (int i = 0; i < 10; ++i)
3532 {
3533 glBindVertexArray(m_vao[i % 2]);
3534 glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, m_xfo[i % 2]);
3535 glBeginTransformFeedback(GL_POINTS);
3536 glDrawArrays(GL_POINTS, 0, 1);
3537 glEndTransformFeedback();
3538 }
3539 {
3540 IVec4 data;
3541 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer[0]);
3542 glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 16, &data[0]);
3543 if (!IsEqual(data, IVec4(20)))
3544 {
3545 m_context.getTestContext().getLog()
3546 << tcu::TestLog::Message << "Data is: " << data[0] << " " << data[1] << " " << data[2] << " "
3547 << data[3] << ", data should be: 20 20 20 20." << tcu::TestLog::EndMessage;
3548 return ERROR;
3549 }
3550 }
3551
3552 if (!RelinkProgram(11))
3553 return ERROR;
3554 glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
3555 glBindVertexArray(m_vao[0]);
3556 glDisableVertexAttribArray(5);
3557 glBindVertexBuffer(5, 0, 0, 0);
3558 glVertexAttribIFormat(11, 4, GL_INT, 0);
3559 glEnableVertexAttribArray(11);
3560 for (int i = 0; i < 10; ++i)
3561 {
3562 glBindVertexBuffer(11, m_buffer[i % 2], 0, 16);
3563 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, m_buffer[(i + 1) % 2]);
3564 glBeginTransformFeedback(GL_POINTS);
3565 glDrawArrays(GL_POINTS, 0, 1);
3566 glEndTransformFeedback();
3567 }
3568 {
3569 IVec4 data;
3570 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, m_buffer[0]);
3571 glGetBufferSubData(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 16, &data[0]);
3572 if (!IsEqual(data, IVec4(30)))
3573 {
3574 m_context.getTestContext().getLog()
3575 << tcu::TestLog::Message << "Data is: " << data[0] << " " << data[1] << " " << data[2] << " "
3576 << data[3] << ", data should be: 30 30 30 30." << tcu::TestLog::EndMessage;
3577 return ERROR;
3578 }
3579 }
3580
3581 return NO_ERROR;
3582 }
3583
RelinkProgram(GLuint index)3584 bool RelinkProgram(GLuint index)
3585 {
3586 glBindAttribLocation(m_po, index, "vs_in_data");
3587 {
3588 const GLchar* const v[1] = { "StageData.data" };
3589 glTransformFeedbackVaryings(m_po, 1, v, GL_INTERLEAVED_ATTRIBS);
3590 }
3591 glLinkProgram(m_po);
3592 if (!CheckProgram(m_po))
3593 return false;
3594 return true;
3595 }
3596 };
3597
3598 //=============================================================================
3599 // 2.4 AdvancedLargeStrideAndOffsetsNewAndLegacyAPI
3600 //-----------------------------------------------------------------------------
3601 class AdvancedLargeStrideAndOffsetsNewAndLegacyAPI : public VertexAttribBindingBase
3602 {
3603 GLuint m_vsp, m_ppo, m_ssbo, m_vao, m_vbo;
3604
Setup()3605 virtual long Setup()
3606 {
3607 m_vsp = 0;
3608 glGenProgramPipelines(1, &m_ppo);
3609 glGenBuffers(1, &m_ssbo);
3610 glGenVertexArrays(1, &m_vao);
3611 glGenBuffers(1, &m_vbo);
3612 return NO_ERROR;
3613 }
3614
Cleanup()3615 virtual long Cleanup()
3616 {
3617 glDisable(GL_RASTERIZER_DISCARD);
3618 glDeleteProgram(m_vsp);
3619 glDeleteProgramPipelines(1, &m_ppo);
3620 glDeleteBuffers(1, &m_ssbo);
3621 glDeleteVertexArrays(1, &m_vao);
3622 glDeleteBuffers(1, &m_vbo);
3623 return NO_ERROR;
3624 }
3625
Run()3626 virtual long Run()
3627 {
3628 const char* const glsl_vs =
3629 "#version 430 core" NL "layout(location = 0) in vec2 vs_in_attrib0;" NL
3630 "layout(location = 4) in ivec2 vs_in_attrib1;" NL "layout(location = 8) in uvec2 vs_in_attrib2;" NL
3631 "layout(location = 15) in float vs_in_attrib3;" NL "layout(std430, binding = 1) buffer Output {" NL
3632 " vec2 attrib0[4];" NL " ivec2 attrib1[4];" NL " uvec2 attrib2[4];" NL " float attrib3[4];" NL
3633 "} g_output;" NL "void main() {" NL
3634 " g_output.attrib0[2 * gl_InstanceID + gl_VertexID] = vs_in_attrib0;" NL
3635 " g_output.attrib1[2 * gl_InstanceID + gl_VertexID] = vs_in_attrib1;" NL
3636 " g_output.attrib2[2 * gl_InstanceID + gl_VertexID] = vs_in_attrib2;" NL
3637 " g_output.attrib3[2 * gl_InstanceID + gl_VertexID] = vs_in_attrib3;" NL "}";
3638 m_vsp = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &glsl_vs);
3639 if (!CheckProgram(m_vsp))
3640 return ERROR;
3641 glUseProgramStages(m_ppo, GL_VERTEX_SHADER_BIT, m_vsp);
3642
3643 {
3644 glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
3645 glBufferData(GL_ARRAY_BUFFER, 100000, NULL, GL_STATIC_DRAW);
3646 GLubyte* ptr = static_cast<GLubyte*>(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
3647
3648 *reinterpret_cast<Vec2*>(&ptr[16 + 0 * 2048]) = Vec2(1.0f, 2.0f);
3649 *reinterpret_cast<Vec2*>(&ptr[16 + 1 * 2048]) = Vec2(3.0f, 4.0f);
3650 *reinterpret_cast<IVec2*>(&ptr[128 + 0 * 2048]) = IVec2(5, 6);
3651 *reinterpret_cast<IVec2*>(&ptr[128 + 1 * 2048]) = IVec2(7, 8);
3652 *reinterpret_cast<UVec2*>(&ptr[1024 + 0 * 2048]) = UVec2(9, 10);
3653 *reinterpret_cast<UVec2*>(&ptr[1024 + 1 * 2048]) = UVec2(11, 12);
3654 *reinterpret_cast<float*>(&ptr[2032 + 0 * 2048]) = 13.0f;
3655 *reinterpret_cast<float*>(&ptr[2032 + 1 * 2048]) = 14.0f;
3656
3657 glUnmapBuffer(GL_ARRAY_BUFFER);
3658 glBindBuffer(GL_ARRAY_BUFFER, 0);
3659 }
3660 glBindVertexArray(m_vao);
3661 glVertexAttribFormat(0, 2, GL_FLOAT, GL_FALSE, 16);
3662 glVertexAttribIFormat(8, 2, GL_UNSIGNED_INT, 1024);
3663 glVertexAttribFormat(15, 1, GL_FLOAT, GL_FALSE, 2032);
3664 glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
3665 glVertexAttribIPointer(4, 2, GL_INT, 2048, reinterpret_cast<void*>(128));
3666 glBindBuffer(GL_ARRAY_BUFFER, 0);
3667 glVertexAttribBinding(8, 3);
3668 glVertexAttribBinding(15, 3);
3669 glBindVertexBuffer(0, m_vbo, 0, 2048);
3670 glBindVertexBuffer(3, m_vbo, 0, 2048);
3671 glEnableVertexAttribArray(0);
3672 glEnableVertexAttribArray(4);
3673 glEnableVertexAttribArray(8);
3674 glEnableVertexAttribArray(15);
3675 glBindVertexArray(0);
3676
3677 std::vector<GLubyte> data((sizeof(Vec2) + sizeof(IVec2) + sizeof(UVec2) + sizeof(float)) * 4, 0xff);
3678 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, m_ssbo);
3679 glBufferData(GL_SHADER_STORAGE_BUFFER, (GLsizeiptr)data.size(), &data[0], GL_DYNAMIC_DRAW);
3680
3681 glEnable(GL_RASTERIZER_DISCARD);
3682 glBindProgramPipeline(m_ppo);
3683 glBindVertexArray(m_vao);
3684 glDrawArraysInstanced(GL_POINTS, 0, 2, 2);
3685
3686 {
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