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