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 "es31cDrawIndirectTests.hpp" 25#include "gluContextInfo.hpp" 26#include "glwEnums.hpp" 27#include "tcuMatrix.hpp" 28#include "tcuRenderTarget.hpp" 29#include "tcuVectorUtil.hpp" 30 31#include <map> 32 33namespace glcts 34{ 35using namespace glw; 36namespace 37{ 38 39class DILogger 40{ 41public: 42 DILogger() : null_log_(0) 43 { 44 } 45 46 DILogger(const DILogger& rhs) 47 { 48 null_log_ = rhs.null_log_; 49 if (!null_log_) 50 { 51 str_ << rhs.str_.str(); 52 } 53 } 54 55 ~DILogger() 56 { 57 s_tcuLog->writeMessage(str_.str().c_str()); 58 if (!str_.str().empty()) 59 { 60 s_tcuLog->writeMessage(NL); 61 } 62 } 63 64 template <class T> 65 DILogger& operator<<(const T& t) 66 { 67 if (!null_log_) 68 { 69 str_ << t; 70 } 71 return *this; 72 } 73 74 DILogger& nullify() 75 { 76 null_log_ = true; 77 return *this; 78 } 79 80 static void setOutput(tcu::TestLog& log) 81 { 82 s_tcuLog = &log; 83 } 84 85private: 86 void operator=(const DILogger&); 87 bool null_log_; 88 std::ostringstream str_; 89 static tcu::TestLog* s_tcuLog; 90}; 91tcu::TestLog* DILogger::s_tcuLog = NULL; 92 93class DIResult 94{ 95public: 96 DIResult() : status_(NO_ERROR) 97 { 98 } 99 100 DILogger error() 101 { 102 return sub_result(ERROR); 103 } 104 long code() const 105 { 106 return status_; 107 } 108 DILogger sub_result(long _code) 109 { 110 if (_code == NO_ERROR) 111 { 112 return sub_result_inner(_code).nullify(); 113 } 114 else 115 { 116 return sub_result_inner(_code); 117 } 118 } 119 120private: 121 DILogger sub_result_inner(long _code) 122 { 123 status_ |= _code; 124 return DILogger(); 125 } 126 DILogger logger_; 127 long status_; 128}; 129 130namespace test_api 131{ 132struct ES3 133{ 134 static bool isES() 135 { 136 return true; 137 } 138 static std::string glslVer(bool = false) 139 { 140 return "#version 310 es"; 141 } 142 static void ES_Only() 143 { 144 } 145}; 146 147struct GL 148{ 149 static bool isES() 150 { 151 return false; 152 } 153 static std::string glslVer(bool compute = false) 154 { 155 if (compute) 156 { 157 return "#version 430"; 158 } 159 else 160 { 161 return "#version 400"; 162 } 163 } 164 static void GL_Only() 165 { 166 } 167}; 168} 169 170namespace shaders 171{ 172 173template <typename api> 174std::string vshSimple() 175{ 176 return api::glslVer() + NL "in vec4 i_vertex;" NL "void main()" NL "{" NL " gl_Position = i_vertex;" NL "}"; 177} 178template <typename api> 179std::string vshSimple_point() 180{ 181 return api::glslVer() + NL "in vec4 i_vertex;" NL "void main()" NL "{" NL " gl_Position = i_vertex;" NL 182 "#if defined(GL_ES)" NL " gl_PointSize = 1.0;" NL "#endif" NL "}"; 183} 184 185template <typename api> 186std::string fshSimple() 187{ 188 return api::glslVer() + NL "precision highp float; " NL "out vec4 outColor;" NL "void main() {" NL 189 " outColor = vec4(0.1,0.2,0.3,1.0);" NL "}"; 190} 191} 192 193class DrawIndirectBase : public glcts::SubcaseBase 194{ 195protected: 196 typedef std::vector<unsigned int> CDataArray; 197 typedef std::vector<tcu::Vec3> CVertexArray; 198 typedef std::vector<tcu::Vec4> CColorArray; 199 typedef std::vector<GLuint> CElementArray; 200 201 enum TDrawFunction 202 { 203 DRAW_ARRAYS, 204 DRAW_ELEMENTS, 205 }; 206 207 typedef struct 208 { 209 GLuint count; 210 GLuint primCount; 211 GLuint first; 212 GLuint reservedMustBeZero; 213 } DrawArraysIndirectCommand; 214 215 typedef struct 216 { 217 GLuint count; 218 GLuint primCount; 219 GLuint firstIndex; 220 GLint baseVertex; 221 GLuint reservedMustBeZero; 222 } DrawElementsIndirectCommand; 223 224 int getWindowWidth() 225 { 226 return m_context.getRenderContext().getRenderTarget().getWidth(); 227 } 228 229 int getWindowHeight() 230 { 231 return m_context.getRenderContext().getRenderTarget().getHeight(); 232 } 233 234 void getDataSize(int& width, int& height) 235 { 236 width = std::min(getWindowWidth(), 16384); // Cap width to 16384 237 height = std::min(getWindowHeight(), 4 * 16384 / width); // Height is 4 if width is capped 238 } 239 240 GLuint CreateComputeProgram(const std::string& cs, bool linkAndCheck) 241 { 242 const GLuint p = glCreateProgram(); 243 244 const GLuint sh = glCreateShader(GL_COMPUTE_SHADER); 245 glAttachShader(p, sh); 246 glDeleteShader(sh); 247 const char* const src[1] = { cs.c_str() }; 248 glShaderSource(sh, 1, src, NULL); 249 glCompileShader(sh); 250 251 if (linkAndCheck) 252 { 253 glLinkProgram(p); 254 if (!CheckProgram(p)) 255 { 256 return 0; 257 } 258 } 259 260 return p; 261 } 262 263 GLuint CreateProgram(const std::string& vs, const std::string& gs, const std::string& fs, bool linkAndCheck) 264 { 265 const GLuint p = glCreateProgram(); 266 267 if (!vs.empty()) 268 { 269 const GLuint sh = glCreateShader(GL_VERTEX_SHADER); 270 glAttachShader(p, sh); 271 glDeleteShader(sh); 272 const char* const src[1] = { vs.c_str() }; 273 glShaderSource(sh, 1, src, NULL); 274 glCompileShader(sh); 275 } 276 if (!gs.empty()) 277 { 278 const GLuint sh = glCreateShader(GL_GEOMETRY_SHADER); 279 glAttachShader(p, sh); 280 glDeleteShader(sh); 281 const char* const src[1] = { gs.c_str() }; 282 glShaderSource(sh, 1, src, NULL); 283 glCompileShader(sh); 284 } 285 if (!fs.empty()) 286 { 287 const GLuint sh = glCreateShader(GL_FRAGMENT_SHADER); 288 glAttachShader(p, sh); 289 glDeleteShader(sh); 290 const char* const src[1] = { fs.c_str() }; 291 glShaderSource(sh, 1, src, NULL); 292 glCompileShader(sh); 293 } 294 295 if (linkAndCheck) 296 { 297 glLinkProgram(p); 298 if (!CheckProgram(p)) 299 { 300 return 0; 301 } 302 } 303 304 return p; 305 } 306 307 long CheckProgram(GLuint program) 308 { 309 DIResult status; 310 GLint progStatus; 311 glGetProgramiv(program, GL_LINK_STATUS, &progStatus); 312 313 if (progStatus == GL_FALSE) 314 { 315 316 status.error() << "GL_LINK_STATUS is false"; 317 318 GLint attached_shaders; 319 glGetProgramiv(program, GL_ATTACHED_SHADERS, &attached_shaders); 320 321 if (attached_shaders > 0) 322 { 323 std::vector<GLuint> shaders(attached_shaders); 324 glGetAttachedShaders(program, attached_shaders, NULL, &shaders[0]); 325 326 for (GLint i = 0; i < attached_shaders; ++i) 327 { 328 // shader type 329 GLenum type; 330 glGetShaderiv(shaders[i], GL_SHADER_TYPE, reinterpret_cast<GLint*>(&type)); 331 switch (type) 332 { 333 case GL_VERTEX_SHADER: 334 status.error() << "*** Vertex Shader ***\n"; 335 break; 336 case GL_FRAGMENT_SHADER: 337 status.error() << "*** Fragment Shader ***\n"; 338 break; 339 case GL_COMPUTE_SHADER: 340 status.error() << "*** Compute Shader ***\n"; 341 break; 342 default: 343 status.error() << "*** Unknown Shader ***\n"; 344 break; 345 } 346 347 // shader source 348 GLint length; 349 glGetShaderiv(shaders[i], GL_SHADER_SOURCE_LENGTH, &length); 350 if (length > 0) 351 { 352 std::vector<GLchar> source(length); 353 glGetShaderSource(shaders[i], length, NULL, &source[0]); 354 status.error() << source[0]; 355 } 356 357 // shader info log 358 glGetShaderiv(shaders[i], GL_INFO_LOG_LENGTH, &length); 359 if (length > 0) 360 { 361 std::vector<GLchar> log(length); 362 glGetShaderInfoLog(shaders[i], length, NULL, &log[0]); 363 status.error() << &log[0]; 364 } 365 } 366 } 367 368 // program info log 369 GLint length; 370 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length); 371 if (length > 0) 372 { 373 std::vector<GLchar> log(length); 374 glGetProgramInfoLog(program, length, NULL, &log[0]); 375 status.error() << &log[0]; 376 } 377 } 378 379 return status.code() == NO_ERROR; 380 } 381 382 template <typename api> 383 void ReadPixelsFloat(int x, int y, int width, int height, void* data); 384 385 template <typename api> 386 void GetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid* data); 387 388 template <typename T> 389 void DataGen(std::vector<T>& data, unsigned int sizeX, unsigned int sizeY, T valueMin, T valueMax) 390 { 391 data.resize(sizeX * sizeY, 0); 392 T range = valueMax - valueMin; 393 T stepX = range / sizeX; 394 T stepY = range / sizeY; 395 396 for (unsigned int i = 0; i < sizeY; ++i) 397 { 398 T valueY = i * stepY; 399 400 for (unsigned int j = 0; j < sizeX; ++j) 401 { 402 data[j + i * sizeX] = valueMin + j * stepX + valueY; 403 } 404 } 405 } 406 407 template <typename T> 408 long DataCompare(const std::vector<T>& dataRef, unsigned int widthRef, unsigned int heightRef, 409 const std::vector<T>& dataTest, unsigned int widthTest, unsigned int heightTest, 410 unsigned offsetYRef = 0, unsigned offsetYTest = 0) 411 { 412 if (widthRef * heightRef > dataRef.size()) 413 throw std::runtime_error("Invalid reference buffer resolution!"); 414 415 if (widthTest * heightTest > dataTest.size()) 416 throw std::runtime_error("Invalid test buffer resolution!"); 417 418 unsigned int width = std::min(widthRef, widthTest); 419 unsigned int height = std::min(heightRef, heightTest); 420 421 for (unsigned int i = 0; i < height; ++i) 422 { 423 unsigned int offsetRef = (i + offsetYRef) * widthRef; 424 unsigned int offsetTest = (i + offsetYTest) * widthTest; 425 426 for (size_t j = 0; j < width; ++j) 427 { 428 if (dataRef[offsetRef + j] != dataTest[offsetTest + j]) 429 { 430 DIResult status; 431 status.error() << "Compare failed: different values [x: " << j << ", y: " << i + offsetYTest 432 << ", reference: " << dataRef[offsetRef + j] 433 << ", test: " << dataTest[offsetTest + j] << "]"; 434 return status.code(); 435 } 436 } 437 } 438 439 return NO_ERROR; 440 } 441 442 template <typename api> 443 long BindingPointCheck(GLuint expectedValue) 444 { 445 DIResult status; 446 447 GLint valueInt = -9999; 448 glGetIntegerv(GL_DRAW_INDIRECT_BUFFER_BINDING, &valueInt); 449 if (valueInt != static_cast<GLint>(expectedValue)) 450 { 451 status.error() << "glGetIntegerv(GL_DRAW_INDIRECT_BUFFER_BINDING) returned invalid value: " << valueInt 452 << ", expected: " << expectedValue; 453 } 454 455 GLboolean valueBool = expectedValue ? GL_FALSE : GL_TRUE; 456 glGetBooleanv(GL_DRAW_INDIRECT_BUFFER_BINDING, &valueBool); 457 if (valueBool != (expectedValue ? GL_TRUE : GL_FALSE)) 458 { 459 status.error() << "glGetBooleanv(GL_DRAW_INDIRECT_BUFFER_BINDING) returned invalid value: " 460 << BoolToString(valueBool) 461 << ", expected: " << BoolToString(expectedValue ? GL_TRUE : GL_FALSE); 462 } 463 464 GLfloat valueFloat = -9999; 465 GLfloat expectedFloatValue = static_cast<GLfloat>(expectedValue); 466 glGetFloatv(GL_DRAW_INDIRECT_BUFFER_BINDING, &valueFloat); 467 if (valueFloat != expectedFloatValue) 468 { 469 status.error() << "glGetFloatv(GL_DRAW_INDIRECT_BUFFER_BINDING) returned invalid value: " << valueFloat 470 << ", expected: " << expectedValue; 471 } 472 473 if (!api::isES()) 474 { 475 GLdouble valueDouble = -9999; 476 glGetDoublev(GL_DRAW_INDIRECT_BUFFER_BINDING, &valueDouble); 477 if (valueDouble != static_cast<GLdouble>(expectedValue)) 478 { 479 status.error() << "glGetDoublev(GL_DRAW_INDIRECT_BUFFER_BINDING) returned invalid value: " 480 << valueDouble << ", expected: " << expectedValue; 481 } 482 } 483 484 return status.code(); 485 } 486 487 template <typename T> 488 long BuffersCompare(const std::vector<T>& bufferTest, unsigned int widthTest, unsigned int heightTest, 489 const std::vector<T>& bufferRef, unsigned int widthRef, unsigned int heightRef) 490 { 491 492 const tcu::PixelFormat& pixelFormat = m_context.getRenderContext().getRenderTarget().getPixelFormat(); 493 tcu::Vec4 epsilon = tcu::Vec4( 494 1.f / static_cast<float>(1 << pixelFormat.redBits), 1.f / static_cast<float>(1 << pixelFormat.greenBits), 495 1.f / static_cast<float>(1 << pixelFormat.blueBits), 1.f / static_cast<float>(1 << pixelFormat.alphaBits)); 496 497 double stepX = widthRef / static_cast<double>(widthTest); 498 double stepY = heightRef / static_cast<double>(heightTest); 499 for (unsigned int i = 0; i < heightTest; ++i) 500 { 501 unsigned int offsetTest = i * widthTest; 502 unsigned int offsetRef = static_cast<int>(i * stepY + 0.5) * widthRef; 503 for (unsigned int j = 0; j < widthTest; ++j) 504 { 505 unsigned int posXRef = static_cast<int>(j * stepX + 0.5); 506 if (!ColorVerify(bufferTest[j + offsetTest], bufferRef[posXRef + offsetRef], epsilon)) 507 { 508 DIResult status; 509 status.error() << "(x,y)= (" << j << "," << i << "). Color RGBA(" << bufferTest[j + offsetTest][0] 510 << "," << bufferTest[j + offsetTest][1] << "," << bufferTest[j + offsetTest][2] 511 << "," << bufferTest[j + offsetTest][3] << ") is different than expected RGBA(" 512 << bufferRef[posXRef + offsetRef][0] << "," << bufferRef[posXRef + offsetRef][1] 513 << "," << bufferRef[posXRef + offsetRef][2] << "," 514 << bufferRef[posXRef + offsetRef][3] << ")"; 515 return status.code(); 516 } 517 } 518 } 519 return NO_ERROR; 520 } 521 522 template <typename T> 523 bool ColorVerify(T color, T colorExpected, tcu::Vec4 epsilon) 524 { 525 for (int i = 0; i < 3; ++i) 526 { 527 if (fabsf(colorExpected[i] - color[i]) > epsilon[i]) 528 return false; 529 } 530 return true; 531 } 532 533 long BufferCheck(const CDataArray& dataRef, unsigned int widthRef, unsigned int heightRef, const void* bufTest, 534 unsigned int widthTest, unsigned int heightTest, unsigned int offsetYRef = 0, 535 unsigned int offsetYTest = 0) 536 { 537 if (bufTest == 0) 538 { 539 throw std::runtime_error("Invalid test buffer!"); 540 } 541 542 CDataArray dataTest(widthTest * heightTest, 0); 543 memcpy(&dataTest[0], bufTest, widthTest * heightTest * sizeof(unsigned int)); 544 545 return DataCompare(dataRef, widthRef, heightRef, dataTest, widthTest, heightTest, offsetYRef, offsetYTest); 546 } 547 548 template <typename api> 549 long StateValidate(GLboolean mapped, GLbitfield access, GLbitfield accessFlag, GLintptr offset, GLsizeiptr length) 550 { 551 DIResult result; 552 553 if (!api::isES()) 554 { 555 int v; 556 glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_ACCESS, &v); 557 if (v != static_cast<int>(access)) 558 { 559 result.error() << "glGetBufferParameteriv(GL_BUFFER_ACCESS) returned incorrect state: " 560 << AccessToString(v) << ", expected: " << AccessToString(access); 561 } 562 } 563 564 int v; 565 glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_ACCESS_FLAGS, &v); 566 if (v != static_cast<int>(accessFlag)) 567 { 568 result.error() << "glGetBufferParameteriv(GL_BUFFER_ACCESS_FLAGS) returned incorrect state: " << v 569 << ", expected: " << accessFlag; 570 } 571 572 glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAPPED, &v); 573 if (v != mapped) 574 { 575 result.error() << "glGetBufferParameteriv(GL_BUFFER_MAPPED) returned incorrect state: " 576 << BoolToString((GLboolean)v) << ", expected: " << BoolToString((GLboolean)access); 577 } 578 579 glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_OFFSET, &v); 580 if (v != offset) 581 { 582 result.error() << "glGetBufferParameteriv(GL_BUFFER_MAP_OFFSET) returned incorrect offset: " << v 583 << ", expected: " << offset; 584 } 585 586 glGetBufferParameteriv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_LENGTH, &v); 587 if (v != length) 588 { 589 result.error() << "glGetBufferParameteriv(GL_BUFFER_MAP_LENGTH) returned incorrect length: " << v 590 << ", expected: " << length; 591 } 592 593 return result.code(); 594 } 595 596 void PointsGen(unsigned int drawSizeX, unsigned int drawSizeY, CColorArray& output) 597 { 598 output.reserve(drawSizeY * 2); 599 float rasterSizeX = 2.0f / static_cast<float>(getWindowWidth()); 600 float rasterSizeY = 2.0f / static_cast<float>(getWindowHeight()); 601 for (unsigned int i = 0; i < drawSizeY; ++i) 602 { 603 float offsetY = -1.0f + rasterSizeY * static_cast<float>(i) + rasterSizeY / 2; 604 for (unsigned int j = 0; j < drawSizeX; ++j) 605 { 606 float offsetX = -1.0f + rasterSizeX * static_cast<float>(j) + rasterSizeX / 2; 607 output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f)); 608 } 609 } 610 } 611 612 float LinesOffsetY(unsigned int i, float rasterSize) 613 { 614 // Offset lines slightly from the center of pixels so as not to hit rasterizer 615 // tie-break conditions (the right-edge of the screen at half-integer pixel 616 // heights is the right corner of a diamond). rasterSize/16 is the smallest 617 // offset that the spec guarantees the rasterizer can resolve. 618 return -1.0f + rasterSize * static_cast<float>(i) + rasterSize / 2 + rasterSize / 16; 619 } 620 621 void LinesGen(unsigned int, unsigned int drawSizeY, CColorArray& output) 622 { 623 output.reserve(drawSizeY * 2); 624 float rasterSize = 2.0f / static_cast<float>(getWindowHeight()); 625 for (unsigned int i = 0; i < drawSizeY; ++i) 626 { 627 float offsetY = LinesOffsetY(i, rasterSize); 628 output.push_back(tcu::Vec4(-1.0f, offsetY, 0.0f, 1.0f)); 629 output.push_back(tcu::Vec4(1.0f, offsetY, 0.0f, 1.0f)); 630 } 631 } 632 633 void LinesAdjacencyGen(unsigned int, unsigned int drawSizeY, CColorArray& output) 634 { 635 float rasterSize = 2.0f / static_cast<float>(getWindowHeight()); 636 for (unsigned int i = 0; i < drawSizeY; ++i) 637 { 638 float offsetY = LinesOffsetY(i, rasterSize); 639 output.push_back(tcu::Vec4(-1.5f, -1.0f + offsetY, 0.0f, 1.0f)); //adj 640 output.push_back(tcu::Vec4(-1.0f, offsetY, 0.0f, 1.0f)); 641 output.push_back(tcu::Vec4(1.0f, offsetY, 0.0f, 1.0f)); 642 output.push_back(tcu::Vec4(1.5f, -1.0f + offsetY, 0.0f, 1.0f)); //adj 643 } 644 } 645 646 void LineStripAdjacencyGen(unsigned int, unsigned int drawSizeY, CColorArray& output) 647 { 648 float rasterSize = 2.0f / static_cast<float>(getWindowHeight()); 649 output.push_back(tcu::Vec4(-1.5f, rasterSize / 2, 0.0f, 1.0f)); 650 for (unsigned int i = 0; i < drawSizeY; ++i) 651 { 652 float offsetY = LinesOffsetY(i, rasterSize); 653 output.push_back(tcu::Vec4(-1.0f, offsetY, 0.0f, 1.0f)); 654 output.push_back(tcu::Vec4(-1.0f, offsetY, 0.0f, 1.0f)); 655 output.push_back(tcu::Vec4(1.0f, offsetY, 0.0f, 1.0f)); 656 output.push_back(tcu::Vec4(1.0f, offsetY, 0.0f, 1.0f)); 657 } 658 output.push_back(tcu::Vec4(1.5f, 1.0f - rasterSize / 2, 0.0f, 1.0f)); 659 } 660 661 void TrianglesGen(unsigned int drawSizeX, unsigned int drawSizeY, CColorArray& output) 662 { 663 output.reserve(drawSizeX * 2 * 6); 664 665 switch (drawSizeX) 666 { 667 case 1: 668 { 669 output.push_back(tcu::Vec4(-1.0f, -1.0f, 0.0f, 1.0f)); 670 output.push_back(tcu::Vec4(4.0f, -1.0f, 0.0f, 1.0f)); 671 output.push_back(tcu::Vec4(-1.0f, 4.0f, 0.0f, 1.0f)); 672 } 673 break; 674 case 0: 675 { 676 throw std::runtime_error("Invalid drawSizeX!"); 677 } 678 break; 679 default: 680 { 681 float drawStepX = 2.0f / static_cast<float>(drawSizeX); 682 float drawStepY = 2.0f / static_cast<float>(drawSizeY); 683 684 for (unsigned int i = 0; i < drawSizeY; ++i) 685 { 686 float offsetY = -1.0f + drawStepY * static_cast<float>(i); 687 for (unsigned int j = 0; j < drawSizeX; ++j) 688 { 689 float offsetX = -1.0f + drawStepX * static_cast<float>(j); 690 691 output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f)); 692 output.push_back(tcu::Vec4(offsetX + drawStepX, offsetY, 0.0f, 1.0f)); 693 output.push_back(tcu::Vec4(offsetX, offsetY + drawStepY, 0.0f, 1.0f)); 694 695 output.push_back(tcu::Vec4(offsetX + drawStepX, offsetY, 0.0f, 1.0f)); 696 output.push_back(tcu::Vec4(offsetX + drawStepX, offsetY + drawStepY, 0.0f, 1.0f)); 697 output.push_back(tcu::Vec4(offsetX, offsetY + drawStepY, 0.0f, 1.0f)); 698 } 699 } 700 } 701 break; 702 } 703 } 704 705 void TrianglesAdjacencyGen(unsigned int drawSizeX, unsigned int drawSizeY, CColorArray& output) 706 { 707 float sizeX = 1.0f / static_cast<float>(drawSizeX); 708 float sizeY = 1.0f / static_cast<float>(drawSizeY); 709 710 for (unsigned int i = 0; i < drawSizeX; ++i) 711 { 712 float offsetY = -0.5f + sizeY * static_cast<float>(i); 713 for (unsigned int j = 0; j < drawSizeY; ++j) 714 { 715 float offsetX = -0.5f + sizeX * static_cast<float>(j); 716 717 output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f)); 718 output.push_back(tcu::Vec4(offsetX - sizeX, offsetY + sizeY, 0.0f, 1.0f)); 719 output.push_back(tcu::Vec4(offsetX, offsetY + sizeY, 0.0f, 1.0f)); 720 output.push_back(tcu::Vec4(offsetX + sizeX, offsetY + sizeY, 0.0f, 1.0f)); 721 output.push_back(tcu::Vec4(offsetX + sizeX, offsetY, 0.0f, 1.0f)); 722 output.push_back(tcu::Vec4(offsetX + sizeX, offsetY - sizeY, 0.0f, 1.0f)); 723 724 output.push_back(tcu::Vec4(offsetX + sizeX, offsetY + sizeY, 0.0f, 1.0f)); 725 output.push_back(tcu::Vec4(offsetX + 2 * sizeX, offsetY, 0.0f, 1.0f)); 726 output.push_back(tcu::Vec4(offsetX + sizeX, offsetY, 0.0f, 1.0f)); 727 output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f)); 728 output.push_back(tcu::Vec4(offsetX, offsetY + sizeY, 0.0f, 1.0f)); 729 output.push_back(tcu::Vec4(offsetX, offsetY + 2 * sizeY, 0.0f, 1.0f)); 730 } 731 } 732 } 733 734 void TriangleStripAdjacencyGen(unsigned int drawSizeX, unsigned int drawSizeY, CColorArray& output) 735 { 736 float sizeX = 1.0f / static_cast<float>(drawSizeX); 737 float sizeY = 1.0f / static_cast<float>(drawSizeY); 738 739 for (unsigned int i = 0; i < drawSizeX; ++i) 740 { 741 float offsetY = -0.5f + sizeY * static_cast<float>(i); 742 for (unsigned int j = 0; j < drawSizeY; ++j) 743 { 744 float offsetX = -0.5f + sizeX * static_cast<float>(j); 745 746 output.push_back(tcu::Vec4(offsetX, offsetY, 0.0f, 1.0f)); 747 output.push_back(tcu::Vec4(offsetX - sizeX, offsetY + sizeY, 0.0f, 1.0f)); 748 output.push_back(tcu::Vec4(offsetX, offsetY + sizeY, 0.0f, 1.0f)); 749 output.push_back(tcu::Vec4(offsetX + sizeX, offsetY - sizeY, 0.0f, 1.0f)); 750 output.push_back(tcu::Vec4(offsetX + sizeX, offsetY, 0.0f, 1.0f)); 751 output.push_back(tcu::Vec4(offsetX, offsetY + 2 * sizeY, 0.0f, 1.0f)); 752 output.push_back(tcu::Vec4(offsetX + sizeX, offsetY + sizeY, 0.0f, 1.0f)); 753 output.push_back(tcu::Vec4(offsetX + 2 * sizeX, offsetY - sizeY, 0.0f, 1.0f)); 754 } 755 } 756 } 757 758 void PrimitiveGen(GLenum primitiveType, unsigned int drawSizeX, unsigned int drawSizeY, CColorArray& output) 759 { 760 switch (primitiveType) 761 { 762 case GL_POINTS: 763 PointsGen(drawSizeX, drawSizeY, output); 764 break; 765 case GL_LINES: 766 case GL_LINE_STRIP: 767 case GL_LINE_LOOP: 768 LinesGen(drawSizeX, drawSizeY, output); 769 break; 770 case GL_LINES_ADJACENCY: 771 LinesAdjacencyGen(drawSizeX, drawSizeY, output); 772 break; 773 case GL_LINE_STRIP_ADJACENCY: 774 LineStripAdjacencyGen(drawSizeX, drawSizeY, output); 775 break; 776 case GL_TRIANGLES: 777 case GL_TRIANGLE_STRIP: 778 case GL_TRIANGLE_FAN: 779 TrianglesGen(drawSizeX, drawSizeY, output); 780 break; 781 case GL_TRIANGLES_ADJACENCY: 782 TrianglesAdjacencyGen(drawSizeX, drawSizeY, output); 783 break; 784 case GL_TRIANGLE_STRIP_ADJACENCY: 785 TriangleStripAdjacencyGen(drawSizeX, drawSizeY, output); 786 break; 787 default: 788 throw std::runtime_error("Unknown primitive type!"); 789 break; 790 } 791 } 792 793 std::string BoolToString(GLboolean value) 794 { 795 if (value == GL_TRUE) 796 return "GL_TRUE"; 797 798 return "GL_FALSE"; 799 } 800 801 std::string AccessToString(GLbitfield access) 802 { 803 switch (access) 804 { 805 case GL_READ_WRITE: 806 return "GL_READ_WRITE"; 807 break; 808 case GL_READ_ONLY: 809 return "GL_READ_ONLY"; 810 break; 811 case GL_WRITE_ONLY: 812 return "GL_WRITE_ONLY"; 813 break; 814 default: 815 throw std::runtime_error("Invalid access type!"); 816 break; 817 } 818 } 819}; 820 821template <> 822void DrawIndirectBase::ReadPixelsFloat<test_api::GL>(int x, int y, int width, int height, void* data) 823{ 824 glReadPixels(x, y, width, height, GL_RGBA, GL_FLOAT, data); 825} 826 827template <> 828void DrawIndirectBase::ReadPixelsFloat<test_api::ES3>(int x, int y, int width, int height, void* data) 829{ 830 GLfloat* fData = reinterpret_cast<GLfloat*>(data); 831 std::vector<GLubyte> uData(width * height * 4); 832 glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &uData[0]); 833 for (size_t i = 0; i < uData.size(); i++) 834 { 835 fData[i] = float(uData[i]) / 255.0f; 836 } 837} 838 839template <> 840void DrawIndirectBase::GetBufferSubData<test_api::GL>(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid* data) 841{ 842 glGetBufferSubData(target, offset, size, data); 843} 844 845template <> 846void DrawIndirectBase::GetBufferSubData<test_api::ES3>(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid* data) 847{ 848 void* ptr = glMapBufferRange(target, offset, size, GL_MAP_READ_BIT); 849 memcpy(data, ptr, size); 850 glUnmapBuffer(target); 851} 852 853template <typename api> 854struct CDefaultBindingPoint : public DrawIndirectBase 855{ 856 virtual std::string Title() 857 { 858 return "Draw Indirect: Check default binding point"; 859 } 860 861 virtual std::string Purpose() 862 { 863 return "Verify that default binding point is set to zero"; 864 } 865 866 virtual std::string Method() 867 { 868 return "Use glGetIntegerv, glGetBooleanv, glGetFloatv, glGetDoublev to get default binding point"; 869 } 870 871 virtual std::string PassCriteria() 872 { 873 return "The test will pass if default binding point is zero"; 874 } 875 876 virtual long Run() 877 { 878 return BindingPointCheck<api>(0); 879 } 880}; 881 882template <typename api> 883struct CZeroBindingPoint : public DrawIndirectBase 884{ 885 virtual std::string Title() 886 { 887 return "Draw Indirect: Zero binding point"; 888 } 889 890 virtual std::string Purpose() 891 { 892 return "Verify that binding point is set to zero"; 893 } 894 895 virtual std::string Method() 896 { 897 return "Bind zero and check that binding point is set to zero"; 898 } 899 900 virtual std::string PassCriteria() 901 { 902 return "The test will pass if binding point is set to zero"; 903 } 904 905 virtual long Run() 906 { 907 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0); 908 909 return BindingPointCheck<api>(0); 910 } 911}; 912 913template <typename api> 914struct CSingleBindingPoint : public DrawIndirectBase 915{ 916 virtual std::string Title() 917 { 918 return "Draw Indirect: Single binding point"; 919 } 920 921 virtual std::string Purpose() 922 { 923 return "Verify that binding point is set to correct value"; 924 } 925 926 virtual std::string Method() 927 { 928 return "Bind non-zero buffer and check that binding point is set to correct value"; 929 } 930 931 virtual std::string PassCriteria() 932 { 933 return "The test will pass if binding point is set to correct value"; 934 } 935 936 virtual long Run() 937 { 938 glGenBuffers(1, &_buffer); 939 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer); 940 941 long ret = BindingPointCheck<api>(_buffer); 942 943 return ret; 944 } 945 946 virtual long Cleanup() 947 { 948 glDeleteBuffers(1, &_buffer); 949 return BindingPointCheck<api>(0); 950 } 951 952private: 953 GLuint _buffer; 954}; 955 956template <typename api> 957class CMultiBindingPoint : public DrawIndirectBase 958{ 959public: 960 virtual std::string Title() 961 { 962 return "Draw Indirect: Multi binding point"; 963 } 964 965 virtual std::string Purpose() 966 { 967 return "Verify that binding points are set to correct value"; 968 } 969 970 virtual std::string Method() 971 { 972 return "Bind in loop non-zero buffers and check that binding points are set to correct value"; 973 } 974 975 virtual std::string PassCriteria() 976 { 977 return "The test will pass if binding points are set to correct value"; 978 } 979 980 virtual long Run() 981 { 982 DIResult result; 983 984 const int buffNum = sizeof(_buffers) / sizeof(_buffers[0]); 985 986 glGenBuffers(buffNum, _buffers); 987 988 for (int i = 0; i < buffNum; ++i) 989 { 990 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[i]); 991 result.sub_result(BindingPointCheck<api>(_buffers[i])); 992 } 993 994 return result.code(); 995 } 996 997 virtual long Cleanup() 998 { 999 glDeleteBuffers(sizeof(_buffers) / sizeof(_buffers[0]), _buffers); 1000 return BindingPointCheck<api>(0); 1001 } 1002 1003private: 1004 GLuint _buffers[10]; 1005}; 1006 1007template <typename api> 1008struct CDeleteBindingPoint : public DrawIndirectBase 1009{ 1010 virtual std::string Title() 1011 { 1012 return "Draw Indirect: Delete binding point"; 1013 } 1014 1015 virtual std::string Purpose() 1016 { 1017 return "Verify that after deleting buffer, binding point is set to correct value"; 1018 } 1019 1020 virtual std::string Method() 1021 { 1022 return "Bind non-zero buffer, delete buffer, check that binding point is set to 0"; 1023 } 1024 1025 virtual std::string PassCriteria() 1026 { 1027 return "The test will pass if binding point is set to correct value"; 1028 } 1029 1030 virtual long Run() 1031 { 1032 glGenBuffers(1, &_buffer); 1033 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer); 1034 glDeleteBuffers(1, &_buffer); 1035 return BindingPointCheck<api>(0); 1036 } 1037 1038private: 1039 GLuint _buffer; 1040}; 1041 1042template <typename api> 1043struct CBufferData : public DrawIndirectBase 1044{ 1045 virtual std::string Title() 1046 { 1047 return "Check functions: glBufferData and GetBufferSubData<api>"; 1048 } 1049 1050 virtual std::string Purpose() 1051 { 1052 return "Verify that glBufferData and GetBufferSubData<api> accepts GL_DRAW_INDIRECT_BUFFER enum"; 1053 } 1054 1055 virtual std::string Method() 1056 { 1057 return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data using glBufferData" NL 1058 "4. Get data using GetBufferSubData<api>" NL "5. Verify results"; 1059 } 1060 1061 virtual std::string PassCriteria() 1062 { 1063 return "The test will pass if no OpenGL errors reported"; 1064 } 1065 1066 virtual long Run() 1067 { 1068 DIResult result; 1069 1070 int dataWidth, dataHeight; 1071 getDataSize(dataWidth, dataHeight); 1072 1073 CDataArray dataTest(dataWidth * dataHeight, 0); 1074 1075 glGenBuffers(sizeof(_buffers) / sizeof(_buffers[0]), _buffers); 1076 CDataArray dataRef1; 1077 DataGen<unsigned int>(dataRef1, dataWidth, dataHeight, 0, 50); 1078 1079 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[1]); 1080 glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef1.size() * sizeof(unsigned int)), &dataRef1[0], 1081 GL_DYNAMIC_DRAW); 1082 result.sub_result(BindingPointCheck<api>(_buffers[1])); 1083 1084 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), 1085 &dataTest[0]); 1086 result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight)); 1087 1088 CDataArray dataRef2; 1089 DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 10, 70); 1090 1091 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[2]); 1092 glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef2.size() * sizeof(unsigned int)), &dataRef2[0], 1093 GL_STREAM_DRAW); 1094 result.sub_result(BindingPointCheck<api>(_buffers[2])); 1095 1096 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), 1097 &dataTest[0]); 1098 result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight)); 1099 1100 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[3]); 1101 glBufferData(GL_DRAW_INDIRECT_BUFFER, 300, NULL, GL_STATIC_DRAW); 1102 result.sub_result(BindingPointCheck<api>(_buffers[3])); 1103 1104 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[4]); 1105 glBufferData(GL_DRAW_INDIRECT_BUFFER, 400, NULL, GL_DYNAMIC_READ); 1106 result.sub_result(BindingPointCheck<api>(_buffers[4])); 1107 1108 CDataArray dataRef5; 1109 DataGen<unsigned int>(dataRef5, dataWidth, dataHeight, 0, 50); 1110 1111 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[5]); 1112 glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef5.size() * sizeof(unsigned int)), &dataRef5[0], 1113 GL_STREAM_READ); 1114 result.sub_result(BindingPointCheck<api>(_buffers[5])); 1115 1116 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), 1117 &dataTest[0]); 1118 result.sub_result(DataCompare(dataRef5, dataWidth, dataHeight, dataTest, dataWidth, dataHeight)); 1119 1120 CDataArray dataRef6; 1121 DataGen<unsigned int>(dataRef6, dataWidth, dataHeight, 10, 40); 1122 1123 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[6]); 1124 glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef6.size() * sizeof(unsigned int)), &dataRef6[0], 1125 GL_STATIC_READ); 1126 result.sub_result(BindingPointCheck<api>(_buffers[6])); 1127 1128 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), 1129 &dataTest[0]); 1130 result.sub_result(DataCompare(dataRef6, dataWidth, dataHeight, dataTest, dataWidth, dataHeight)); 1131 1132 CDataArray dataRef7; 1133 DataGen<unsigned int>(dataRef7, dataWidth, dataHeight, 4, 70); 1134 1135 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[7]); 1136 glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef7.size() * sizeof(unsigned int)), &dataRef7[0], 1137 GL_DYNAMIC_COPY); 1138 result.sub_result(BindingPointCheck<api>(_buffers[7])); 1139 1140 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), 1141 &dataTest[0]); 1142 result.sub_result(DataCompare(dataRef7, dataWidth, dataHeight, dataTest, dataWidth, dataHeight)); 1143 1144 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[8]); 1145 glBufferData(GL_DRAW_INDIRECT_BUFFER, 800, NULL, GL_STREAM_COPY); 1146 result.sub_result(BindingPointCheck<api>(_buffers[8])); 1147 1148 CDataArray dataRef9; 1149 DataGen<unsigned int>(dataRef9, dataWidth, dataHeight, 18, 35); 1150 1151 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[9]); 1152 glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef9.size() * sizeof(unsigned int)), &dataRef9[0], 1153 GL_STATIC_COPY); 1154 result.sub_result(BindingPointCheck<api>(_buffers[9])); 1155 1156 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), 1157 &dataTest[0]); 1158 result.sub_result(DataCompare(dataRef9, dataWidth, dataHeight, dataTest, dataWidth, dataHeight)); 1159 1160 //reallocation: same size 1161 glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef9.size() * sizeof(unsigned int)), &dataRef9[0], 1162 GL_STATIC_COPY); 1163 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), 1164 &dataTest[0]); 1165 result.sub_result(DataCompare(dataRef9, dataWidth, dataHeight, dataTest, dataWidth, dataHeight)); 1166 1167 //reallocation: larger size 1168 DataGen<unsigned int>(dataRef9, dataWidth * 2, dataHeight * 2, 18, 35); 1169 dataTest.resize(dataRef9.size()); 1170 glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef9.size() * sizeof(unsigned int)), &dataRef9[0], 1171 GL_STATIC_COPY); 1172 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), 1173 &dataTest[0]); 1174 result.sub_result( 1175 DataCompare(dataRef9, dataWidth * 2, dataHeight * 2, dataTest, dataWidth * 2, dataHeight * 2)); 1176 1177 //reallocation: smaller size 1178 DataGen<unsigned int>(dataRef9, dataWidth / 2, dataHeight / 2, 18, 35); 1179 dataTest.resize(dataRef9.size()); 1180 glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef9.size() * sizeof(unsigned int)), &dataRef9[0], 1181 GL_STATIC_COPY); 1182 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), 1183 &dataTest[0]); 1184 result.sub_result( 1185 DataCompare(dataRef9, dataWidth / 2, dataHeight / 2, dataTest, dataWidth / 2, dataHeight / 2)); 1186 1187 return result.code(); 1188 } 1189 1190 virtual long Cleanup() 1191 { 1192 glDeleteBuffers(sizeof(_buffers) / sizeof(_buffers[0]), _buffers); 1193 return BindingPointCheck<api>(0); 1194 } 1195 1196private: 1197 GLuint _buffers[10]; 1198}; 1199 1200template <typename api> 1201struct CBufferSubData : public DrawIndirectBase 1202{ 1203 virtual std::string Title() 1204 { 1205 return "Check function: glBufferSubData and GetBufferSubData<api>"; 1206 } 1207 1208 virtual std::string Purpose() 1209 { 1210 return "Verify that glBufferSubData and GetBufferSubData<api> accepts GL_DRAW_INDIRECT_BUFFER enum"; 1211 } 1212 1213 virtual std::string Method() 1214 { 1215 return "1. Create buffer" NL "2. Bind buffer" NL "3. Allocate buffer using glBufferData" NL 1216 "4. Set data using glBufferSubData" NL "5. Get data using GetBufferSubData<api>" NL "6. Verify results"; 1217 } 1218 1219 virtual std::string PassCriteria() 1220 { 1221 return "The test will pass if no OpenGL errors reported"; 1222 } 1223 1224 virtual long Run() 1225 { 1226 DIResult result; 1227 1228 glGenBuffers(1, &_buffer); 1229 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer); 1230 1231 CDataArray dataRef; 1232 int dataWidth, dataHeight; 1233 getDataSize(dataWidth, dataHeight); 1234 DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 4, 70); 1235 glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), NULL, 1236 GL_DYNAMIC_DRAW); 1237 glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0]); 1238 1239 CDataArray dataTest(dataWidth * dataHeight, 0); 1240 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), 1241 &dataTest[0]); 1242 1243 result.sub_result(DataCompare(dataRef, dataWidth, dataHeight, dataTest, dataWidth, dataHeight)); 1244 1245 CDataArray dataSubRef; 1246 DataGen<unsigned int>(dataSubRef, dataWidth / 2, dataHeight / 2, 80, 90); 1247 glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 4, (GLsizeiptr)(dataSubRef.size() * sizeof(unsigned int)), 1248 &dataSubRef[0]); 1249 std::copy(dataSubRef.begin(), dataSubRef.end(), dataRef.begin() + 1); 1250 1251 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), 1252 &dataTest[0]); 1253 result.sub_result(DataCompare(dataRef, dataWidth, dataHeight, dataTest, dataWidth, dataHeight)); 1254 1255 return result.code(); 1256 } 1257 1258 virtual long Cleanup() 1259 { 1260 glDeleteBuffers(1, &_buffer); 1261 return BindingPointCheck<api>(0); 1262 } 1263 1264private: 1265 GLuint _buffer; 1266}; 1267 1268template <typename api> 1269struct CBufferMap : public DrawIndirectBase 1270{ 1271 virtual std::string Title() 1272 { 1273 return "Check functions: glMapBuffer, glUnmapBuffer and getParameteriv"; 1274 } 1275 1276 virtual std::string Purpose() 1277 { 1278 return "Verify that glMapBuffer, glUnmapBuffer and getParameteriv accepts GL_DRAW_INDIRECT_BUFFER enum"; 1279 } 1280 1281 virtual std::string Method() 1282 { 1283 return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Map buffer" NL 1284 "5. Verify mapped buffer" NL "6. Check state" NL "7. Unmap buffer" NL "8. Check state"; 1285 } 1286 1287 virtual std::string PassCriteria() 1288 { 1289 return "The test will pass if no OpenGL errors reported"; 1290 } 1291 1292 virtual long Run() 1293 { 1294 DIResult result; 1295 1296 api::GL_Only(); 1297 1298 glGenBuffers(1, &_buffer); 1299 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer); 1300 1301 CDataArray dataRef; 1302 int dataWidth, dataHeight; 1303 getDataSize(dataWidth, dataHeight); 1304 DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 30, 50); 1305 glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0], 1306 GL_DYNAMIC_DRAW); 1307 1308 result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0)); 1309 1310 void* buf = glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_ONLY); 1311 if (buf == 0) 1312 { 1313 result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_ONLY) returned NULL"; 1314 } 1315 1316 if (buf) 1317 { 1318 result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, buf, dataWidth, dataHeight)); 1319 1320 result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_ONLY, GL_MAP_READ_BIT, 0, 1321 (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)))); 1322 1323 if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE) 1324 { 1325 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE"; 1326 } 1327 buf = 0; 1328 1329 result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0)); 1330 } 1331 1332 buf = glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_WRITE_ONLY); 1333 if (buf == 0) 1334 { 1335 result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_WRITE_ONLY) returned NULL"; 1336 } 1337 1338 if (buf) 1339 { 1340 result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, buf, dataWidth, dataHeight)); 1341 1342 result.sub_result(StateValidate<api>(GL_TRUE, GL_WRITE_ONLY, GL_MAP_WRITE_BIT, 0, 1343 (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)))); 1344 1345 if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) != GL_TRUE) 1346 { 1347 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE"; 1348 } 1349 buf = 0; 1350 1351 result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0)); 1352 } 1353 1354 buf = glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_WRITE); 1355 if (buf == 0) 1356 { 1357 result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_READ_WRITE) returned NULL"; 1358 } 1359 1360 if (buf) 1361 { 1362 result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, buf, dataWidth, dataHeight)); 1363 1364 result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_WRITE, GL_MAP_WRITE_BIT | GL_MAP_READ_BIT, 0, 1365 (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)))); 1366 1367 if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE) 1368 { 1369 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE"; 1370 } 1371 buf = 0; 1372 1373 result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0)); 1374 } 1375 1376 return result.code(); 1377 } 1378 1379 virtual long Cleanup() 1380 { 1381 glDeleteBuffers(1, &_buffer); 1382 return BindingPointCheck<api>(0); 1383 } 1384 1385private: 1386 GLuint _buffer; 1387}; 1388 1389template <typename api> 1390struct CBufferGetPointerv : public DrawIndirectBase 1391{ 1392 virtual std::string Title() 1393 { 1394 return "Check functions: glBuffergetPointerv"; 1395 } 1396 1397 virtual std::string Purpose() 1398 { 1399 return "Verify that glBuffergetPointerv accepts GL_DRAW_INDIRECT_BUFFER enum"; 1400 } 1401 1402 virtual std::string Method() 1403 { 1404 return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Map buffer" NL 1405 "5. Get a pointer to buffer" NL "6. Compare pointers from point 4) and 5)" NL 1406 "7. Verify mapped buffer" NL "8. Unmap buffer"; 1407 } 1408 1409 virtual std::string PassCriteria() 1410 { 1411 return "The test will pass if no OpenGL errors reported"; 1412 } 1413 1414 virtual long Run() 1415 { 1416 DIResult result; 1417 1418 glGenBuffers(1, &_buffer); 1419 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer); 1420 1421 CDataArray dataRef; 1422 int dataWidth, dataHeight; 1423 getDataSize(dataWidth, dataHeight); 1424 DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 30, 50); 1425 glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0], 1426 GL_DYNAMIC_DRAW); 1427 1428 void* ptr = 0; 1429 glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER, &ptr); 1430 1431 if (ptr != 0) 1432 { 1433 result.error() << "glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER) returned invalid " 1434 "pointer, expected: NULL"; 1435 } 1436 1437 void* buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), 1438 GL_MAP_READ_BIT); 1439 if (buf == 0) 1440 { 1441 result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL"; 1442 1443 return result.code(); 1444 } 1445 1446 glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER, &ptr); 1447 1448 if (ptr == 0) 1449 { 1450 result.error() << "glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER) returned NULL"; 1451 } 1452 1453 if (ptr) 1454 { 1455 result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, ptr, dataWidth, dataHeight)); 1456 } 1457 1458 if (ptr != buf) 1459 { 1460 result.error() << "glGetBufferPointerv(GL_DRAW_INDIRECT_BUFFER, GL_BUFFER_MAP_POINTER) different pointer " 1461 "than glMapBuffer(GL_DRAW_INDIRECT_BUFFER)"; 1462 } 1463 1464 if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE) 1465 { 1466 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE"; 1467 } 1468 buf = 0; 1469 ptr = 0; 1470 1471 return result.code(); 1472 } 1473 1474 virtual long Cleanup() 1475 { 1476 glDeleteBuffers(1, &_buffer); 1477 return BindingPointCheck<api>(0); 1478 } 1479 1480private: 1481 GLuint _buffer; 1482}; 1483 1484template <class api> 1485struct CBufferMapRange : public DrawIndirectBase 1486{ 1487 virtual std::string Title() 1488 { 1489 return "Check functions: glMapRangeBuffer, glUnmapBuffer and getParameteriv"; 1490 } 1491 1492 virtual std::string Purpose() 1493 { 1494 return "Verify that glMapRangeBuffer, glUnmapBuffer and getParameteriv accepts GL_DRAW_INDIRECT_BUFFER enum"; 1495 } 1496 1497 virtual std::string Method() 1498 { 1499 return "Bind non-zero buffer and check that binding point is set to correct value"; 1500 } 1501 1502 virtual std::string PassCriteria() 1503 { 1504 return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Map buffer using glMapBufferRange" NL 1505 "5. Check state" NL "6. Verify mapped buffer" NL "7. Unmap buffer" NL "8. Check state"; 1506 } 1507 1508 virtual long Run() 1509 { 1510 DIResult result; 1511 1512 glGenBuffers(1, &_buffer); 1513 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer); 1514 1515 CDataArray dataRef; 1516 int dataWidth, dataHeight; 1517 getDataSize(dataWidth, dataHeight); 1518 DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 30, 50); 1519 glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0], 1520 GL_DYNAMIC_DRAW); 1521 1522 result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0)); 1523 1524 void* buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), 1525 GL_MAP_READ_BIT); 1526 if (buf == 0) 1527 { 1528 result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL"; 1529 } 1530 1531 if (buf) 1532 { 1533 result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight, buf, dataWidth, dataHeight)); 1534 1535 result.sub_result(StateValidate<api>(GL_TRUE, GL_READ_ONLY, GL_MAP_READ_BIT, 0, 1536 (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)))); 1537 1538 if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE) 1539 { 1540 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE"; 1541 } 1542 buf = 0; 1543 1544 result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0)); 1545 } 1546 1547 buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int)), 1548 GL_MAP_WRITE_BIT); 1549 if (buf == 0) 1550 { 1551 result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_WRITE_BIT) returned NULL"; 1552 } 1553 1554 if (buf) 1555 { 1556 result.sub_result(BufferCheck(dataRef, dataWidth, dataHeight / 2, buf, dataWidth, dataHeight / 2)); 1557 1558 result.sub_result(StateValidate<api>(GL_TRUE, GL_WRITE_ONLY, GL_MAP_WRITE_BIT, 0, 1559 (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int)))); 1560 1561 if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE) 1562 { 1563 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE"; 1564 } 1565 buf = 0; 1566 1567 result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0)); 1568 } 1569 1570 buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, (GLintptr)(dataRef.size() / 4 * sizeof(unsigned int)), 1571 (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int)), GL_MAP_WRITE_BIT); 1572 if (buf == 0) 1573 { 1574 result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_WRITE_BIT) returned NULL"; 1575 } 1576 1577 if (buf) 1578 { 1579 result.sub_result( 1580 BufferCheck(dataRef, dataWidth, dataHeight / 2, buf, dataWidth, dataHeight / 2, dataHeight / 4)); 1581 1582 result.sub_result(StateValidate<api>(GL_TRUE, GL_WRITE_ONLY, GL_MAP_WRITE_BIT, 1583 (GLintptr)(dataRef.size() / 4 * sizeof(unsigned int)), 1584 (GLsizeiptr)(dataRef.size() / 2 * sizeof(unsigned int)))); 1585 1586 if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE) 1587 { 1588 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE"; 1589 } 1590 buf = 0; 1591 1592 result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0)); 1593 } 1594 1595 return result.code(); 1596 } 1597 1598 virtual long Cleanup() 1599 { 1600 glDeleteBuffers(1, &_buffer); 1601 return BindingPointCheck<api>(0); 1602 } 1603 1604private: 1605 GLuint _buffer; 1606}; 1607 1608template <class api> 1609struct CBufferFlushMappedRange : public DrawIndirectBase 1610{ 1611 virtual std::string Title() 1612 { 1613 return "Check functions: glFlushMappedBufferRange"; 1614 } 1615 1616 virtual std::string Purpose() 1617 { 1618 return "Verify that glFlushMappedBufferRange and getParameteriv accepts GL_DRAW_INDIRECT_BUFFER enum"; 1619 } 1620 1621 virtual std::string Method() 1622 { 1623 return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL 1624 "4. Map buffer with GL_MAP_FLUSH_EXPLICIT_BIT flag" NL "5. Check state" NL "6. Modify mapped buffer" NL 1625 "7. Flush buffer" NL "8. Unmap buffer" NL "9. Check state" NL "10. Verify buffer"; 1626 } 1627 1628 virtual std::string PassCriteria() 1629 { 1630 return "The test will pass if no OpenGL errors reported"; 1631 } 1632 1633 virtual long Run() 1634 { 1635 DIResult result; 1636 1637 glGenBuffers(1, &_buffer); 1638 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer); 1639 1640 CDataArray dataRef; 1641 int dataWidth, dataHeight; 1642 getDataSize(dataWidth, dataHeight); 1643 DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 1, 1000); 1644 1645 CDataArray dataRef2; 1646 DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 1000, 2000); 1647 1648 const int halfSize = dataHeight / 2 * dataWidth; 1649 const int quarterSize = dataHeight / 4 * dataWidth; 1650 1651 glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef.size() * sizeof(unsigned int)), &dataRef[0], 1652 GL_DYNAMIC_DRAW); 1653 1654 result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0)); 1655 1656 void* buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, quarterSize * sizeof(unsigned int), 1657 halfSize * sizeof(unsigned int), GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); 1658 1659 if (buf == 0) 1660 { 1661 result.error() << "glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, GL_MAP_WRITE_BIT) returned NULL"; 1662 } 1663 1664 if (buf) 1665 { 1666 result.sub_result(StateValidate<api>(GL_TRUE, GL_WRITE_ONLY, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT, 1667 quarterSize * sizeof(unsigned int), halfSize * sizeof(unsigned int))); 1668 1669 memcpy(buf, &dataRef2[quarterSize], halfSize * sizeof(unsigned int)); 1670 glFlushMappedBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, halfSize * sizeof(unsigned int)); 1671 1672 if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) == GL_FALSE) 1673 { 1674 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE"; 1675 } 1676 buf = 0; 1677 1678 result.sub_result(StateValidate<api>(GL_FALSE, GL_READ_WRITE, 0, 0, 0)); 1679 } 1680 1681 CDataArray dataTest(dataWidth * dataHeight, 0); 1682 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), 1683 &dataTest[0]); 1684 1685 result.sub_result(DataCompare(dataRef, dataWidth, dataHeight / 4, dataTest, dataWidth, dataHeight / 4)); 1686 1687 result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight / 2, dataTest, dataWidth, dataHeight / 2, 1688 dataHeight / 4, dataHeight / 4)); 1689 1690 result.sub_result(DataCompare(dataRef, dataWidth, dataHeight / 4, dataTest, dataWidth, dataHeight / 4, 1691 dataHeight * 3 / 4, dataHeight * 3 / 4)); 1692 1693 return result.code(); 1694 } 1695 1696 virtual long Cleanup() 1697 { 1698 glDeleteBuffers(1, &_buffer); 1699 return BindingPointCheck<api>(0); 1700 } 1701 1702private: 1703 GLuint _buffer; 1704}; 1705 1706template <class api> 1707struct CBufferBindRange : public DrawIndirectBase 1708{ 1709 virtual std::string Title() 1710 { 1711 return "Check functions: glBindBufferRange"; 1712 } 1713 1714 virtual std::string Purpose() 1715 { 1716 return "Verify that glBindBufferRange accepts GL_DRAW_INDIRECT_BUFFER enum"; 1717 } 1718 1719 virtual std::string Method() 1720 { 1721 return "1. Create buffer" NL "2. Bind buffer using glBindBufferRange" NL "3. Set data" NL "4. Verify buffer"; 1722 } 1723 1724 virtual std::string PassCriteria() 1725 { 1726 return "The test will pass if no OpenGL errors reported"; 1727 } 1728 1729 virtual long Run() 1730 { 1731 DIResult result; 1732 1733 glGenBuffers(1, &_buffer); 1734 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffer); 1735 1736 CDataArray dataRef; 1737 int dataWidth, dataHeight; 1738 getDataSize(dataWidth, dataHeight); 1739 DataGen<unsigned int>(dataRef, dataWidth, dataHeight, 1, 100); 1740 glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef.size() * sizeof(unsigned int), &dataRef[0], GL_DYNAMIC_DRAW); 1741 1742 CDataArray dataTest(dataWidth * dataHeight, 0); 1743 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]); 1744 result.sub_result(DataCompare(dataRef, dataWidth, dataHeight, dataTest, dataWidth, dataHeight)); 1745 1746 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0); 1747 result.sub_result(BindingPointCheck<api>(0)); 1748 1749 glBindBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, _buffer, 0, dataTest.size() * sizeof(unsigned int) / 4); 1750 result.sub_result(BindingPointCheck<api>(_buffer)); 1751 1752 CDataArray dataRef2; 1753 DataGen<unsigned int>(dataRef2, dataWidth, dataHeight / 2, 10, 15); 1754 glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef2.size() * sizeof(unsigned int) / 4, &dataRef2[0], 1755 GL_DYNAMIC_DRAW); 1756 1757 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]); 1758 result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight / 4, dataTest, dataWidth, dataHeight / 4)); 1759 result.sub_result(DataCompare(dataRef, dataWidth, dataHeight * 3 / 4, dataTest, dataWidth, dataHeight * 3 / 4, 1760 dataHeight / 4, dataHeight / 4)); 1761 1762 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0); 1763 result.sub_result(BindingPointCheck<api>(0)); 1764 1765 glBindBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, _buffer, dataTest.size() * sizeof(unsigned int) / 4, 1766 dataTest.size() * sizeof(unsigned int) / 4); 1767 result.sub_result(BindingPointCheck<api>(_buffer)); 1768 1769 glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef2.size() * sizeof(unsigned int) / 2, 1770 &dataRef2[dataRef2.size() / 2], GL_DYNAMIC_DRAW); 1771 result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight / 2, dataTest, dataWidth, dataHeight / 2)); 1772 result.sub_result(DataCompare(dataRef, dataWidth, dataHeight / 2, dataTest, dataWidth, dataHeight / 2, 1773 dataHeight / 2, dataHeight / 2)); 1774 1775 return result.code(); 1776 } 1777 1778 virtual long Cleanup() 1779 { 1780 glDeleteBuffers(1, &_buffer); 1781 1782 return BindingPointCheck<api>(0); 1783 } 1784 1785private: 1786 GLuint _buffer; 1787}; 1788 1789template <class api> 1790struct CBufferBindBase : public DrawIndirectBase 1791{ 1792 virtual std::string Title() 1793 { 1794 return "Check functions: glBindBufferBase"; 1795 } 1796 1797 virtual std::string Purpose() 1798 { 1799 return "Verify that glBindBufferBase accepts GL_DRAW_INDIRECT_BUFFER enum"; 1800 } 1801 1802 virtual std::string Method() 1803 { 1804 return "1. Create buffer" NL "2. Bind buffer using glBindBufferBase" NL "3. Set data" NL "4. Verify buffer"; 1805 } 1806 1807 virtual std::string PassCriteria() 1808 { 1809 return "The test will pass if no OpenGL errors reported"; 1810 } 1811 1812 virtual long Run() 1813 { 1814 DIResult result; 1815 1816 glGenBuffers(2, _buffers); 1817 1818 int dataWidth, dataHeight; 1819 getDataSize(dataWidth, dataHeight); 1820 CDataArray dataTest(dataWidth * dataHeight, 0); 1821 1822 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[0]); 1823 CDataArray dataRef1; 1824 DataGen<unsigned int>(dataRef1, dataWidth, dataHeight, 1, 100); 1825 glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef1.size() * sizeof(unsigned int), &dataRef1[0], GL_DYNAMIC_DRAW); 1826 1827 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0); 1828 result.sub_result(BindingPointCheck<api>(0)); 1829 1830 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]); 1831 result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight)); 1832 result.sub_result(BindingPointCheck<api>(_buffers[0])); 1833 1834 glBindBufferBase(GL_DRAW_INDIRECT_BUFFER, 0, _buffers[1]); 1835 result.sub_result(BindingPointCheck<api>(_buffers[1])); 1836 1837 CDataArray dataRef2; 1838 DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 50, 70); 1839 glBufferData(GL_DRAW_INDIRECT_BUFFER, dataRef2.size() * sizeof(unsigned int), &dataRef2[0], GL_DYNAMIC_DRAW); 1840 1841 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, dataTest.size() * sizeof(unsigned int), &dataTest[0]); 1842 result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight)); 1843 1844 result.sub_result(BindingPointCheck<api>(_buffers[1])); 1845 1846 return result.code(); 1847 } 1848 1849 virtual long Cleanup() 1850 { 1851 glDeleteBuffers(2, _buffers); 1852 return BindingPointCheck<api>(0); 1853 } 1854 1855private: 1856 GLuint _buffers[2]; 1857}; 1858 1859template <class api> 1860struct CBufferCopySubData : public DrawIndirectBase 1861{ 1862 virtual std::string Title() 1863 { 1864 return "Check functions: glCopyBufferSubData"; 1865 } 1866 1867 virtual std::string Purpose() 1868 { 1869 return "Verify that glCopyBufferSubData accepts GL_DRAW_INDIRECT_BUFFER enum"; 1870 } 1871 1872 virtual std::string Method() 1873 { 1874 return "1. Create buffer" NL "2. Bind buffer" NL "3. Set data" NL "4. Verify buffer" NL 1875 "5. Modify buffer using glCopyBufferSubData" NL "6. Verify buffer"; 1876 } 1877 1878 virtual std::string PassCriteria() 1879 { 1880 return "The test will pass if no OpenGL errors reported"; 1881 } 1882 1883 virtual long Run() 1884 { 1885 DIResult result; 1886 int dataWidth, dataHeight; 1887 getDataSize(dataWidth, dataHeight); 1888 CDataArray dataTest(dataWidth * dataHeight, 0); 1889 1890 glGenBuffers(2, _buffers); 1891 glBindBuffer(GL_ARRAY_BUFFER, _buffers[0]); 1892 1893 CDataArray dataRef1; 1894 DataGen<unsigned int>(dataRef1, dataWidth, dataHeight, 1, 100); 1895 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(dataRef1.size() * sizeof(unsigned int)), &dataRef1[0], 1896 GL_DYNAMIC_DRAW); 1897 1898 GetBufferSubData<api>(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), &dataTest[0]); 1899 result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight)); 1900 1901 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _buffers[1]); 1902 1903 CDataArray dataRef2; 1904 DataGen<unsigned int>(dataRef2, dataWidth, dataHeight, 10, 30); 1905 glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef2.size() * sizeof(unsigned int)), &dataRef2[0], 1906 GL_DYNAMIC_DRAW); 1907 1908 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), 1909 &dataTest[0]); 1910 result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight)); 1911 1912 glCopyBufferSubData(GL_ARRAY_BUFFER, GL_DRAW_INDIRECT_BUFFER, 0, 0, 1913 (GLsizeiptr)(dataTest.size() * sizeof(unsigned int))); 1914 1915 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), 1916 &dataTest[0]); 1917 result.sub_result(DataCompare(dataRef1, dataWidth, dataHeight, dataTest, dataWidth, dataHeight)); 1918 1919 glBufferData(GL_DRAW_INDIRECT_BUFFER, (GLsizeiptr)(dataRef2.size() * sizeof(unsigned int)), &dataRef2[0], 1920 GL_DYNAMIC_DRAW); 1921 1922 GetBufferSubData<api>(GL_DRAW_INDIRECT_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), 1923 &dataTest[0]); 1924 result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight)); 1925 1926 glCopyBufferSubData(GL_DRAW_INDIRECT_BUFFER, GL_ARRAY_BUFFER, 0, 0, 1927 (GLsizeiptr)(dataTest.size() * sizeof(unsigned int))); 1928 1929 GetBufferSubData<api>(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(dataTest.size() * sizeof(unsigned int)), &dataTest[0]); 1930 result.sub_result(DataCompare(dataRef2, dataWidth, dataHeight, dataTest, dataWidth, dataHeight)); 1931 1932 return result.code(); 1933 } 1934 1935 virtual long Cleanup() 1936 { 1937 glDeleteBuffers(2, _buffers); 1938 return BindingPointCheck<api>(0); 1939 } 1940 1941private: 1942 GLuint _buffers[2]; 1943}; 1944 1945class CBasicVertexDef : public DrawIndirectBase 1946{ 1947public: 1948 virtual long Setup() 1949 { 1950 glClear(GL_COLOR_BUFFER_BIT); 1951 return NO_ERROR; 1952 } 1953 1954 template <typename api> 1955 long Run() 1956 { 1957 CColorArray coords; 1958 PrimitiveGen(_primitiveType, _drawSizeX, _drawSizeY, coords); 1959 1960 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 1961 if (!_program) 1962 { 1963 return ERROR; 1964 } 1965 glUseProgram(_program); 1966 1967 glGenBuffers(1, &_vbo); 1968 glBindBuffer(GL_ARRAY_BUFFER, _vbo); 1969 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STATIC_DRAW); 1970 1971 glGenVertexArrays(1, &_vao); 1972 glBindVertexArray(_vao); 1973 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 1974 glEnableVertexAttribArray(0); 1975 1976 DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 }; 1977 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 1978 1979 CElementArray elements(coords.size(), 0); 1980 for (size_t i = 0; i < elements.size(); ++i) 1981 { 1982 elements[i] = static_cast<GLuint>(i); 1983 } 1984 1985 switch (_drawFunc) 1986 { 1987 case DRAW_ARRAYS: 1988 { 1989 indirectArrays.count = static_cast<GLuint>(coords.size()); 1990 indirectArrays.primCount = 1; 1991 indirectArrays.first = 0; 1992 indirectArrays.reservedMustBeZero = 0; 1993 1994 { 1995 GLuint buffer; 1996 glGenBuffers(1, &buffer); 1997 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer); 1998 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW); 1999 glDrawArraysIndirect(_primitiveType, 0); 2000 glDeleteBuffers(1, &buffer); 2001 } 2002 } 2003 break; 2004 case DRAW_ELEMENTS: 2005 { 2006 indirectElements.count = static_cast<GLuint>(coords.size()); 2007 indirectElements.primCount = 1; 2008 indirectElements.firstIndex = 0; 2009 indirectElements.baseVertex = 0; 2010 indirectElements.reservedMustBeZero = 0; 2011 2012 glGenBuffers(1, &_ebo); 2013 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 2014 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 2015 GL_STATIC_DRAW); 2016 2017 { 2018 GLuint buffer; 2019 glGenBuffers(1, &buffer); 2020 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer); 2021 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW); 2022 glDrawElementsIndirect(_primitiveType, GL_UNSIGNED_INT, 0); 2023 glDeleteBuffers(1, &buffer); 2024 } 2025 } 2026 break; 2027 default: 2028 throw std::runtime_error("Unknown draw function!"); 2029 break; 2030 } 2031 2032 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f)); 2033 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 2034 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 2035 2036 DIResult result; 2037 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 2038 getWindowHeight())); 2039 2040 return result.code(); 2041 } 2042 2043 virtual long Cleanup() 2044 { 2045 glDisableVertexAttribArray(0); 2046 glBindBuffer(GL_ARRAY_BUFFER, 0); 2047 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 2048 glBindVertexArray(0); 2049 glUseProgram(0); 2050 2051 if (_vao) 2052 { 2053 glDeleteVertexArrays(1, &_vao); 2054 } 2055 if (_vbo) 2056 { 2057 glDeleteBuffers(1, &_vbo); 2058 } 2059 if (_ebo) 2060 { 2061 glDeleteBuffers(1, &_ebo); 2062 } 2063 if (_program) 2064 { 2065 glDeleteProgram(_program); 2066 } 2067 2068 return NO_ERROR; 2069 } 2070 2071 CBasicVertexDef(TDrawFunction drawFunc, GLenum primitiveType, unsigned int drawSizeX, unsigned int drawSizeY) 2072 : _drawFunc(drawFunc) 2073 , _primitiveType(primitiveType) 2074 , _drawSizeX(drawSizeX) 2075 , _drawSizeY(drawSizeY) 2076 , _vao(0) 2077 , _vbo(0) 2078 , _ebo(0) 2079 , _program(0) 2080 { 2081 } 2082 2083private: 2084 TDrawFunction _drawFunc; 2085 GLenum _primitiveType; 2086 unsigned int _drawSizeX; 2087 unsigned int _drawSizeY; 2088 2089 GLuint _vao; 2090 GLuint _vbo, _ebo; 2091 GLuint _program; 2092 2093 CBasicVertexDef() 2094 { 2095 } 2096}; 2097 2098class CBasicVertexInstancingDef : public DrawIndirectBase 2099{ 2100public: 2101 virtual long Setup() 2102 { 2103 glClear(GL_COLOR_BUFFER_BIT); 2104 return NO_ERROR; 2105 } 2106 2107 template <typename api> 2108 long Run() 2109 { 2110 CColorArray coords; 2111 PrimitiveGen(GL_TRIANGLES, _drawSizeX, _drawSizeY, coords); 2112 2113 CColorArray coords_instanced(4); 2114 coords_instanced[0] = tcu::Vec4(0.5, 0.5, 0.0, 0.0); 2115 coords_instanced[1] = tcu::Vec4(-0.5, 0.5, 0.0, 0.0); 2116 coords_instanced[2] = tcu::Vec4(-0.5, -0.5, 0.0, 0.0); 2117 coords_instanced[3] = tcu::Vec4(0.5, -0.5, 0.0, 0.0); 2118 2119 CColorArray colors_instanced(2); 2120 colors_instanced[0] = tcu::Vec4(1.0, 0.0, 0.0, 1.0); 2121 colors_instanced[1] = tcu::Vec4(0.0, 1.0, 0.0, 1.0); 2122 2123 _program = CreateProgram(Vsh<api>(), "", Fsh<api>(), true); 2124 if (!_program) 2125 { 2126 return ERROR; 2127 } 2128 glUseProgram(_program); 2129 2130 glGenBuffers(1, &_vbo); 2131 glBindBuffer(GL_ARRAY_BUFFER, _vbo); 2132 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0]) + 2133 coords_instanced.size() * sizeof(coords_instanced[0]) + 2134 colors_instanced.size() * sizeof(colors_instanced[0])), 2135 NULL, GL_STATIC_DRAW); 2136 2137 const size_t coords_offset = 0; 2138 const size_t coords_instanced_offset = coords_offset + coords.size() * sizeof(coords[0]); 2139 const size_t colors_instanced_offset = 2140 coords_instanced_offset + coords_instanced.size() * sizeof(coords_instanced[0]); 2141 2142 glBufferSubData(GL_ARRAY_BUFFER, coords_offset, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0]); 2143 glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)coords_instanced_offset, 2144 (GLsizeiptr)(coords_instanced.size() * sizeof(coords_instanced[0])), &coords_instanced[0]); 2145 glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)colors_instanced_offset, 2146 (GLsizeiptr)(colors_instanced.size() * sizeof(colors_instanced[0])), &colors_instanced[0]); 2147 2148 glGenVertexArrays(1, &_vao); 2149 glBindVertexArray(_vao); 2150 2151 //i_vertex (coords) 2152 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid*>(coords_offset)); 2153 glEnableVertexAttribArray(0); 2154 2155 //i_vertex_instanced (coords_instanced) 2156 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid*>(coords_instanced_offset)); 2157 glEnableVertexAttribArray(1); 2158 glVertexAttribDivisor(1, 1); 2159 2160 //i_vertex_color_instanced (color_instanced) 2161 glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid*>(colors_instanced_offset)); 2162 glEnableVertexAttribArray(2); 2163 glVertexAttribDivisor(2, 3); 2164 2165 DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 }; 2166 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 2167 2168 CElementArray elements(coords.size(), 0); 2169 for (size_t i = 0; i < elements.size(); ++i) 2170 { 2171 elements[i] = static_cast<GLuint>(i); 2172 } 2173 2174 switch (_drawFunc) 2175 { 2176 case DRAW_ARRAYS: 2177 { 2178 indirectArrays.count = static_cast<GLuint>(coords.size()); 2179 indirectArrays.primCount = 4; 2180 indirectArrays.first = 0; 2181 indirectArrays.reservedMustBeZero = 0; 2182 2183 { 2184 GLuint buffer; 2185 glGenBuffers(1, &buffer); 2186 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer); 2187 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW); 2188 glDrawArraysIndirect(GL_TRIANGLES, 0); 2189 glDeleteBuffers(1, &buffer); 2190 } 2191 } 2192 break; 2193 case DRAW_ELEMENTS: 2194 { 2195 indirectElements.count = static_cast<GLuint>(coords.size()); 2196 indirectElements.primCount = 4; 2197 indirectElements.firstIndex = 0; 2198 indirectElements.baseVertex = 0; 2199 indirectElements.reservedMustBeZero = 0; 2200 2201 glGenBuffers(1, &_ebo); 2202 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 2203 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 2204 GL_STATIC_DRAW); 2205 2206 { 2207 GLuint buffer; 2208 glGenBuffers(1, &buffer); 2209 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer); 2210 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW); 2211 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0); 2212 glDeleteBuffers(1, &buffer); 2213 } 2214 } 2215 break; 2216 default: 2217 throw std::runtime_error("Unknown draw function!"); 2218 break; 2219 } 2220 2221 CColorArray bufferRef1(getWindowWidth() / 2 * getWindowHeight() / 2, colors_instanced[0]); 2222 CColorArray bufferRef2(getWindowWidth() / 2 * getWindowHeight() / 2, colors_instanced[1]); 2223 2224 CColorArray bufferTest(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f)); 2225 DIResult result; 2226 2227 ReadPixelsFloat<api>(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, &bufferTest[0]); 2228 result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1, 2229 getWindowWidth() / 2, getWindowHeight() / 2)); 2230 2231 ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, 0, getWindowWidth() / 2, getWindowHeight() / 2, 2232 &bufferTest[0]); 2233 result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef2, 2234 getWindowWidth() / 2, getWindowHeight() / 2)); 2235 2236 ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth() / 2, getWindowHeight() / 2, 2237 &bufferTest[0]); 2238 result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1, 2239 getWindowWidth() / 2, getWindowHeight() / 2)); 2240 2241 ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, (getWindowHeight() + 1) / 2, getWindowWidth() / 2, 2242 getWindowHeight() / 2, &bufferTest[0]); 2243 result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1, 2244 getWindowWidth() / 2, getWindowHeight() / 2)); 2245 2246 return result.code(); 2247 } 2248 2249 virtual long Cleanup() 2250 { 2251 glDisableVertexAttribArray(0); 2252 glBindBuffer(GL_ARRAY_BUFFER, 0); 2253 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 2254 glBindVertexArray(0); 2255 glUseProgram(0); 2256 2257 if (_vao) 2258 { 2259 glDeleteVertexArrays(1, &_vao); 2260 } 2261 if (_vbo) 2262 { 2263 glDeleteBuffers(1, &_vbo); 2264 } 2265 if (_ebo) 2266 { 2267 glDeleteBuffers(1, &_ebo); 2268 } 2269 if (_program) 2270 { 2271 glDeleteProgram(_program); 2272 } 2273 2274 return NO_ERROR; 2275 } 2276 2277 template <typename api> 2278 std::string Vsh() 2279 { 2280 return api::glslVer() + NL 2281 "layout(location = 0) in vec4 i_vertex;" NL "layout(location = 1) in vec4 i_vertex_instanced;" NL 2282 "layout(location = 2) in vec4 i_vertex_color_instanced;" NL "out vec4 vertex_color_instanced;" NL 2283 "void main()" NL "{" NL " gl_Position = vec4(i_vertex.xyz * .5, 1.0) + i_vertex_instanced;" NL 2284 " vertex_color_instanced = i_vertex_color_instanced;" NL "}"; 2285 } 2286 2287 template <typename api> 2288 std::string Fsh() 2289 { 2290 return api::glslVer() + NL "precision highp float; " NL "in vec4 vertex_color_instanced;" NL 2291 "out vec4 outColor;" NL "void main() {" NL " outColor = vertex_color_instanced;" NL 2292 "}"; 2293 } 2294 2295 CBasicVertexInstancingDef(TDrawFunction drawFunc) 2296 : _drawFunc(drawFunc), _drawSizeX(2), _drawSizeY(2), _vao(0), _vbo(0), _ebo(0), _program(0) 2297 { 2298 } 2299 2300private: 2301 TDrawFunction _drawFunc; 2302 unsigned int _drawSizeX; 2303 unsigned int _drawSizeY; 2304 2305 GLuint _vao; 2306 GLuint _vbo, _ebo; 2307 GLuint _program; 2308 2309 CBasicVertexInstancingDef() 2310 { 2311 } 2312}; 2313 2314template <typename api> 2315class CVBODrawArraysSingle : public CBasicVertexDef 2316{ 2317public: 2318 virtual std::string Title() 2319 { 2320 return "VBO: Single primitive using glDrawArraysIndirect"; 2321 } 2322 2323 virtual std::string Purpose() 2324 { 2325 return "Verify that the vertex attributes can be sourced from VBO for glDrawArraysIndirect"; 2326 } 2327 2328 virtual std::string Method() 2329 { 2330 return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL 2331 "3. Verify results"; 2332 } 2333 2334 virtual std::string PassCriteria() 2335 { 2336 return "The test will pass if no OpenGL errors reported"; 2337 } 2338 2339 CVBODrawArraysSingle() : CBasicVertexDef(DRAW_ARRAYS, GL_TRIANGLES, 1, 1) 2340 { 2341 } 2342 virtual long Run() 2343 { 2344 return CBasicVertexDef::Run<api>(); 2345 } 2346}; 2347 2348template <typename api> 2349class CVBODrawArraysMany : public CBasicVertexDef 2350{ 2351public: 2352 virtual std::string Title() 2353 { 2354 return "VBO: Many primitives using glDrawArraysIndirect"; 2355 } 2356 2357 virtual std::string Purpose() 2358 { 2359 return "Verify that the vertex attributes can be sourced from VBO for glDrawArraysIndirect"; 2360 } 2361 2362 virtual std::string Method() 2363 { 2364 return "1. Define primitives using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL 2365 "3. Verify results"; 2366 } 2367 2368 virtual std::string PassCriteria() 2369 { 2370 return "The test will pass if no OpenGL errors reported"; 2371 } 2372 2373 CVBODrawArraysMany() : CBasicVertexDef(DRAW_ARRAYS, GL_TRIANGLES, 8, 8) 2374 { 2375 } 2376 virtual long Run() 2377 { 2378 return CBasicVertexDef::Run<api>(); 2379 } 2380}; 2381 2382template <typename api> 2383class CVBODrawArraysInstancing : public CBasicVertexInstancingDef 2384{ 2385public: 2386 virtual std::string Title() 2387 { 2388 return "VBO: Single primitive using glDrawArraysIndirect, multiple instances"; 2389 } 2390 2391 virtual std::string Purpose() 2392 { 2393 return "Verify that the vertex attributes can be sourced from VBO for glDrawArraysIndirect"; 2394 } 2395 2396 virtual std::string Method() 2397 { 2398 return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL 2399 "3. Verify results"; 2400 } 2401 2402 virtual std::string PassCriteria() 2403 { 2404 return "The test will pass if no OpenGL errors reported"; 2405 } 2406 2407 CVBODrawArraysInstancing() : CBasicVertexInstancingDef(DRAW_ARRAYS) 2408 { 2409 } 2410 virtual long Run() 2411 { 2412 return CBasicVertexInstancingDef::Run<api>(); 2413 } 2414}; 2415 2416class CBasicXFBPausedDef : public DrawIndirectBase 2417{ 2418public: 2419 virtual long Setup() 2420 { 2421 glClear(GL_COLOR_BUFFER_BIT); 2422 return NO_ERROR; 2423 } 2424 2425 template <typename api> 2426 long Run() 2427 { 2428 CColorArray coords; 2429 PrimitiveGen(GL_TRIANGLES, _drawSizeX, _drawSizeY, coords); 2430 2431 _program = CreateProgram(Vsh<api>(), "", shaders::fshSimple<api>(), false); 2432 2433 const GLchar* varyings[] = { "dataOut" }; 2434 glTransformFeedbackVaryings(_program, 1, varyings, GL_INTERLEAVED_ATTRIBS); 2435 glLinkProgram(_program); 2436 if (!CheckProgram(_program)) 2437 { 2438 return ERROR; 2439 } 2440 glUseProgram(_program); 2441 2442 glGenBuffers(1, &_vbo); 2443 glBindBuffer(GL_ARRAY_BUFFER, _vbo); 2444 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STATIC_DRAW); 2445 2446 glGenVertexArrays(1, &_vao); 2447 glBindVertexArray(_vao); 2448 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 2449 glEnableVertexAttribArray(0); 2450 2451 DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 }; 2452 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 2453 2454 CElementArray elements(coords.size(), 0); 2455 for (size_t i = 0; i < elements.size(); ++i) 2456 { 2457 elements[i] = static_cast<GLuint>(i); 2458 } 2459 2460 glGenTransformFeedbacks(1, &_xfo); 2461 glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, _xfo); 2462 2463 glGenBuffers(1, &_xfbo); 2464 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, _xfbo); 2465 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1024, NULL, GL_STATIC_DRAW); 2466 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _xfbo); 2467 2468 glBeginTransformFeedback(GL_TRIANGLES); 2469 glPauseTransformFeedback(); 2470 2471 switch (_drawFunc) 2472 { 2473 case DRAW_ARRAYS: 2474 { 2475 indirectArrays.count = static_cast<GLuint>(coords.size()); 2476 indirectArrays.primCount = 1; 2477 indirectArrays.first = 0; 2478 indirectArrays.reservedMustBeZero = 0; 2479 2480 { 2481 GLuint buffer; 2482 glGenBuffers(1, &buffer); 2483 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer); 2484 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW); 2485 glDrawArraysIndirect(GL_TRIANGLES, 0); 2486 glDeleteBuffers(1, &buffer); 2487 } 2488 } 2489 break; 2490 case DRAW_ELEMENTS: 2491 { 2492 indirectElements.count = static_cast<GLuint>(coords.size()); 2493 indirectElements.primCount = 1; 2494 indirectElements.firstIndex = 0; 2495 indirectElements.baseVertex = 0; 2496 indirectElements.reservedMustBeZero = 0; 2497 2498 glGenBuffers(1, &_ebo); 2499 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 2500 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 2501 GL_STATIC_DRAW); 2502 2503 { 2504 GLuint buffer; 2505 glGenBuffers(1, &buffer); 2506 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer); 2507 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW); 2508 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0); 2509 glDeleteBuffers(1, &buffer); 2510 } 2511 } 2512 2513 break; 2514 default: 2515 throw std::runtime_error("Unknown draw function!"); 2516 break; 2517 } 2518 2519 glResumeTransformFeedback(); 2520 glEndTransformFeedback(); 2521 2522 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f)); 2523 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 2524 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 2525 2526 DIResult result; 2527 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 2528 getWindowHeight())); 2529 2530 return result.code(); 2531 } 2532 2533 virtual long Cleanup() 2534 { 2535 glDisableVertexAttribArray(0); 2536 glBindBuffer(GL_ARRAY_BUFFER, 0); 2537 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 2538 glBindVertexArray(0); 2539 glUseProgram(0); 2540 2541 if (_vao) 2542 { 2543 glDeleteVertexArrays(1, &_vao); 2544 } 2545 if (_vbo) 2546 { 2547 glDeleteBuffers(1, &_vbo); 2548 } 2549 if (_ebo) 2550 { 2551 glDeleteBuffers(1, &_ebo); 2552 } 2553 if (_xfbo) 2554 { 2555 glDeleteBuffers(1, &_xfbo); 2556 } 2557 if (_program) 2558 { 2559 glDeleteProgram(_program); 2560 } 2561 if (_xfo) 2562 { 2563 glDeleteTransformFeedbacks(1, &_xfo); 2564 } 2565 2566 return NO_ERROR; 2567 } 2568 2569 template <typename api> 2570 std::string Vsh() 2571 { 2572 return api::glslVer() + NL "in vec4 i_vertex;" NL "out vec4 dataOut;" NL "void main()" NL "{" NL 2573 " gl_Position = i_vertex;" NL " dataOut = i_vertex;" NL "}"; 2574 } 2575 2576 CBasicXFBPausedDef(TDrawFunction drawFunc) 2577 : _drawFunc(drawFunc), _drawSizeX(2), _drawSizeY(2), _vao(0), _vbo(0), _ebo(0), _xfbo(0), _program(0), _xfo(0) 2578 { 2579 } 2580 2581private: 2582 TDrawFunction _drawFunc; 2583 unsigned int _drawSizeX; 2584 unsigned int _drawSizeY; 2585 2586 GLuint _vao; 2587 GLuint _vbo, _ebo, _xfbo; 2588 GLuint _program; 2589 GLuint _xfo; 2590 2591 CBasicXFBPausedDef() 2592 { 2593 } 2594}; 2595 2596template <typename api> 2597class CVBODrawArraysXFBPaused : public CBasicXFBPausedDef 2598{ 2599public: 2600 virtual std::string Title() 2601 { 2602 return "VBO: glDrawArraysIndirect, in paused transform feedback operation"; 2603 } 2604 2605 virtual std::string Purpose() 2606 { 2607 return "Verify glDrawArraysIndirect works, if XFB is active and paused"; 2608 } 2609 2610 virtual std::string Method() 2611 { 2612 return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL 2613 "3. Verify results"; 2614 } 2615 2616 virtual std::string PassCriteria() 2617 { 2618 return "The test will pass if no OpenGL errors reported"; 2619 } 2620 2621 CVBODrawArraysXFBPaused() : CBasicXFBPausedDef(DRAW_ARRAYS) 2622 { 2623 } 2624 virtual long Run() 2625 { 2626 return CBasicXFBPausedDef::Run<api>(); 2627 } 2628}; 2629 2630template <typename api> 2631class CVBODrawElementsSingle : public CBasicVertexDef 2632{ 2633public: 2634 virtual std::string Title() 2635 { 2636 return "VBO: Single primitive using glDrawElementsIndirect"; 2637 } 2638 2639 virtual std::string Purpose() 2640 { 2641 return "Verify that the vertex attributes can be sourced from VBO for glDrawElementsIndirect"; 2642 } 2643 2644 virtual std::string Method() 2645 { 2646 return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawElementsIndirect" NL 2647 "3. Verify results"; 2648 } 2649 2650 virtual std::string PassCriteria() 2651 { 2652 return "The test will pass if no OpenGL errors reported"; 2653 } 2654 2655 CVBODrawElementsSingle() : CBasicVertexDef(DRAW_ELEMENTS, GL_TRIANGLES, 1, 1) 2656 { 2657 } 2658 virtual long Run() 2659 { 2660 return CBasicVertexDef::Run<api>(); 2661 } 2662}; 2663 2664template <typename api> 2665class CVBODrawElementsMany : public CBasicVertexDef 2666{ 2667public: 2668 virtual std::string Title() 2669 { 2670 return "VBO: Many primitives using glDrawElementsIndirect"; 2671 } 2672 2673 virtual std::string Purpose() 2674 { 2675 return "Verify that the vertex attributes can be sourced from VBO for glDrawElementsIndirect"; 2676 } 2677 2678 virtual std::string Method() 2679 { 2680 return "1. Define primitives using VBO" NL "2. Draw primitive using glDrawElementsIndirect" NL 2681 "3. Verify results"; 2682 } 2683 2684 virtual std::string PassCriteria() 2685 { 2686 return "The test will pass if no OpenGL errors reported"; 2687 } 2688 2689 CVBODrawElementsMany() : CBasicVertexDef(DRAW_ELEMENTS, GL_TRIANGLES, 8, 8) 2690 { 2691 } 2692 2693 virtual long Run() 2694 { 2695 return CBasicVertexDef::Run<api>(); 2696 } 2697}; 2698 2699template <typename api> 2700class CVBODrawElementsInstancing : public CBasicVertexInstancingDef 2701{ 2702public: 2703 virtual std::string Title() 2704 { 2705 return "VBO: Single primitive using glDrawElementsIndirect, multiple instances"; 2706 } 2707 2708 virtual std::string Purpose() 2709 { 2710 return "Verify that the vertex attributes can be sourced from VBO for glDrawElementsIndirect"; 2711 } 2712 2713 virtual std::string Method() 2714 { 2715 return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawElementsIndirect" NL 2716 "3. Verify results"; 2717 } 2718 2719 virtual std::string PassCriteria() 2720 { 2721 return "The test will pass if no OpenGL errors reported"; 2722 } 2723 2724 CVBODrawElementsInstancing() : CBasicVertexInstancingDef(DRAW_ELEMENTS) 2725 { 2726 } 2727 virtual long Run() 2728 { 2729 return CBasicVertexInstancingDef::Run<api>(); 2730 } 2731}; 2732 2733template <typename api> 2734class CVBODrawElementsXFBPaused : public CBasicXFBPausedDef 2735{ 2736public: 2737 virtual std::string Title() 2738 { 2739 return "VBO: glDrawElementsIndirect, in paused transform feedback operation"; 2740 } 2741 2742 virtual std::string Purpose() 2743 { 2744 return "Verify glDrawElementsIndirect works, if XFB is active and paused"; 2745 } 2746 2747 virtual std::string Method() 2748 { 2749 return "1. Define a primitive using VBO" NL "2. Draw primitive using glDrawArraysIndirect" NL 2750 "3. Verify results"; 2751 } 2752 2753 virtual std::string PassCriteria() 2754 { 2755 return "The test will pass if no OpenGL errors reported"; 2756 } 2757 2758 CVBODrawElementsXFBPaused() : CBasicXFBPausedDef(DRAW_ELEMENTS) 2759 { 2760 } 2761 virtual long Run() 2762 { 2763 return CBasicXFBPausedDef::Run<api>(); 2764 } 2765}; 2766 2767template <typename api> 2768class CBufferIndirectDrawArraysSimple : public DrawIndirectBase 2769{ 2770public: 2771 virtual std::string Title() 2772 { 2773 return "Indirect buffer glDrawArraysIndirect: many primitives simple"; 2774 } 2775 2776 virtual std::string Purpose() 2777 { 2778 return "Verify that it is possible to draw primitives with specified indirect structure" NL "in a buffer"; 2779 } 2780 2781 virtual std::string Method() 2782 { 2783 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 2784 "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results"; 2785 } 2786 2787 virtual std::string PassCriteria() 2788 { 2789 return "The test will pass if no OpenGL errors reported"; 2790 } 2791 2792 virtual long Setup() 2793 { 2794 glClear(GL_COLOR_BUFFER_BIT); 2795 return NO_ERROR; 2796 } 2797 2798 virtual long Run() 2799 { 2800 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 2801 if (!_program) 2802 { 2803 return ERROR; 2804 } 2805 glUseProgram(_program); 2806 2807 CColorArray coords; 2808 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 2809 2810 glGenVertexArrays(1, &_vao); 2811 glBindVertexArray(_vao); 2812 2813 glGenBuffers(1, &_buffer); 2814 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 2815 2816 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 2817 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 2818 glEnableVertexAttribArray(0); 2819 2820 DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 }; 2821 indirectArrays.count = static_cast<GLuint>(coords.size()); 2822 indirectArrays.primCount = 1; 2823 indirectArrays.first = 0; 2824 indirectArrays.reservedMustBeZero = 0; 2825 2826 glGenBuffers(1, &_bufferIndirect); 2827 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 2828 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW); 2829 2830 glDrawArraysIndirect(GL_TRIANGLES, 0); 2831 2832 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f)); 2833 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 2834 2835 DIResult result; 2836 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 2837 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 2838 getWindowHeight())); 2839 2840 return result.code(); 2841 } 2842 2843 virtual long Cleanup() 2844 { 2845 glDisableVertexAttribArray(0); 2846 glUseProgram(0); 2847 glDeleteProgram(_program); 2848 glDeleteVertexArrays(1, &_vao); 2849 glDeleteBuffers(1, &_buffer); 2850 glDeleteBuffers(1, &_bufferIndirect); 2851 return NO_ERROR; 2852 } 2853 2854private: 2855 GLuint _program; 2856 GLuint _vao, _buffer, _bufferIndirect; 2857}; 2858 2859template <typename api> 2860class CBufferIndirectDrawArraysNoFirst : public DrawIndirectBase 2861{ 2862public: 2863 virtual std::string Title() 2864 { 2865 return "Indirect buffer glDrawArraysIndirect: non-zero 'first' argument"; 2866 } 2867 2868 virtual std::string Purpose() 2869 { 2870 return "Verify that it is possible to draw primitives with specified non-zero 'first' argument" NL 2871 "in indirect buffer"; 2872 } 2873 2874 virtual std::string Method() 2875 { 2876 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 2877 "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results"; 2878 } 2879 2880 virtual std::string PassCriteria() 2881 { 2882 return "The test will pass if no OpenGL errors reported"; 2883 } 2884 2885 virtual long Setup() 2886 { 2887 glClear(GL_COLOR_BUFFER_BIT); 2888 return NO_ERROR; 2889 } 2890 2891 virtual long Run() 2892 { 2893 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 2894 if (!_program) 2895 { 2896 return ERROR; 2897 } 2898 glUseProgram(_program); 2899 2900 CColorArray coords; 2901 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 2902 2903 glGenVertexArrays(1, &_vao); 2904 glBindVertexArray(_vao); 2905 2906 glGenBuffers(1, &_buffer); 2907 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 2908 2909 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 2910 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 2911 glEnableVertexAttribArray(0); 2912 2913 DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 }; 2914 indirectArrays.count = static_cast<GLuint>(coords.size()) / 2; 2915 indirectArrays.primCount = 1; 2916 indirectArrays.first = static_cast<GLuint>(coords.size()) / 2; 2917 indirectArrays.reservedMustBeZero = 0; 2918 2919 glGenBuffers(1, &_bufferIndirect); 2920 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 2921 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW); 2922 2923 glDrawArraysIndirect(GL_TRIANGLES, 0); 2924 2925 CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f)); 2926 CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f)); 2927 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 2928 2929 DIResult result; 2930 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]); 2931 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1, 2932 getWindowWidth(), getWindowHeight() / 2)); 2933 2934 ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]); 2935 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2, 2936 getWindowWidth(), getWindowHeight() / 2)); 2937 2938 return result.code(); 2939 } 2940 2941 virtual long Cleanup() 2942 { 2943 glDisableVertexAttribArray(0); 2944 glUseProgram(0); 2945 glDeleteProgram(_program); 2946 glDeleteVertexArrays(1, &_vao); 2947 glDeleteBuffers(1, &_buffer); 2948 glDeleteBuffers(1, &_bufferIndirect); 2949 return NO_ERROR; 2950 } 2951 2952private: 2953 GLuint _program; 2954 GLuint _vao, _buffer, _bufferIndirect; 2955}; 2956 2957template <typename api> 2958class CBufferIndirectDrawArraysOffset : public DrawIndirectBase 2959{ 2960public: 2961 virtual std::string Title() 2962 { 2963 return "Indirect buffer glDrawArraysIndirect: offset as a function parameter"; 2964 } 2965 2966 virtual std::string Purpose() 2967 { 2968 return "Verify that it is possible to draw primitives with offset as a function parameter"; 2969 } 2970 2971 virtual std::string Method() 2972 { 2973 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 2974 "3. Draw primitives using glDrawArraysIndirect with offset" NL "4. Verify results"; 2975 } 2976 2977 virtual std::string PassCriteria() 2978 { 2979 return "The test will pass if no OpenGL errors reported"; 2980 } 2981 2982 virtual long Setup() 2983 { 2984 glClear(GL_COLOR_BUFFER_BIT); 2985 return NO_ERROR; 2986 } 2987 2988 virtual long Run() 2989 { 2990 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 2991 if (!_program) 2992 { 2993 return ERROR; 2994 } 2995 glUseProgram(_program); 2996 2997 CColorArray coords; 2998 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 2999 3000 glGenVertexArrays(1, &_vao); 3001 glBindVertexArray(_vao); 3002 3003 glGenBuffers(1, &_buffer); 3004 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 3005 3006 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 3007 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 3008 glEnableVertexAttribArray(0); 3009 3010 DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 }; 3011 indirectArrays.count = static_cast<GLuint>(coords.size()); 3012 indirectArrays.primCount = 1; 3013 indirectArrays.first = 0; 3014 indirectArrays.reservedMustBeZero = 0; 3015 3016 glGenBuffers(1, &_bufferIndirect); 3017 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 3018 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand) * 3, NULL, GL_STATIC_DRAW); 3019 glBufferSubData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), sizeof(DrawArraysIndirectCommand), 3020 &indirectArrays); 3021 glDrawArraysIndirect(GL_TRIANGLES, (void*)sizeof(DrawArraysIndirectCommand)); 3022 3023 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f)); 3024 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 3025 3026 DIResult result; 3027 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 3028 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 3029 getWindowHeight())); 3030 3031 return result.code(); 3032 } 3033 3034 virtual long Cleanup() 3035 { 3036 glDisableVertexAttribArray(0); 3037 glUseProgram(0); 3038 glDeleteProgram(_program); 3039 glDeleteVertexArrays(1, &_vao); 3040 glDeleteBuffers(1, &_buffer); 3041 glDeleteBuffers(1, &_bufferIndirect); 3042 return NO_ERROR; 3043 } 3044 3045private: 3046 GLuint _program; 3047 GLuint _vao, _buffer, _bufferIndirect; 3048}; 3049 3050template <typename api> 3051class CBufferIndirectDrawElementsSimple : public DrawIndirectBase 3052{ 3053public: 3054 virtual std::string Title() 3055 { 3056 return "Indirect buffer glDrawElementsIndirect: many primitives simple"; 3057 } 3058 3059 virtual std::string Purpose() 3060 { 3061 return "Verify that it is possible to draw primitives with specified indirect structure" NL "in a buffer"; 3062 } 3063 3064 virtual std::string Method() 3065 { 3066 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 3067 "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results"; 3068 } 3069 3070 virtual std::string PassCriteria() 3071 { 3072 return "The test will pass if no OpenGL errors reported"; 3073 } 3074 3075 virtual long Setup() 3076 { 3077 glClear(GL_COLOR_BUFFER_BIT); 3078 return NO_ERROR; 3079 } 3080 3081 virtual long Run() 3082 { 3083 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 3084 if (!_program) 3085 { 3086 return ERROR; 3087 } 3088 glUseProgram(_program); 3089 3090 CColorArray coords; 3091 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 3092 3093 glGenVertexArrays(1, &_vao); 3094 glBindVertexArray(_vao); 3095 3096 glGenBuffers(1, &_buffer); 3097 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 3098 3099 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 3100 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 3101 glEnableVertexAttribArray(0); 3102 3103 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 3104 indirectElements.count = static_cast<GLuint>(coords.size()); 3105 indirectElements.primCount = 1; 3106 indirectElements.baseVertex = 0; 3107 indirectElements.firstIndex = 0; 3108 indirectElements.reservedMustBeZero = 0; 3109 3110 CElementArray elements(coords.size(), 0); 3111 for (size_t i = 0; i < elements.size(); ++i) 3112 { 3113 elements[i] = static_cast<GLuint>(i); 3114 } 3115 3116 glGenBuffers(1, &_bufferIndirect); 3117 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 3118 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW); 3119 3120 glGenBuffers(1, &_ebo); 3121 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 3122 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 3123 GL_STATIC_DRAW); 3124 3125 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0); 3126 3127 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f)); 3128 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 3129 3130 DIResult result; 3131 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 3132 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 3133 getWindowHeight())); 3134 3135 return result.code(); 3136 } 3137 3138 virtual long Cleanup() 3139 { 3140 glDisableVertexAttribArray(0); 3141 glUseProgram(0); 3142 glDeleteProgram(_program); 3143 glDeleteVertexArrays(1, &_vao); 3144 glDeleteBuffers(1, &_buffer); 3145 glDeleteBuffers(1, &_bufferIndirect); 3146 glDeleteBuffers(1, &_ebo); 3147 return NO_ERROR; 3148 } 3149 3150private: 3151 GLuint _program; 3152 GLuint _vao, _buffer, _bufferIndirect, _ebo; 3153}; 3154 3155template <typename api> 3156class CBufferIndirectDrawElementsNoFirstIndex : public DrawIndirectBase 3157{ 3158public: 3159 virtual std::string Title() 3160 { 3161 return "Indirect buffer glDrawElementsIndirect: non-zero first index"; 3162 } 3163 3164 virtual std::string Purpose() 3165 { 3166 return "Verify that it is possible to draw primitives with non-zero first index" NL "in indirect buffer"; 3167 } 3168 3169 virtual std::string Method() 3170 { 3171 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 3172 "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results"; 3173 } 3174 3175 virtual std::string PassCriteria() 3176 { 3177 return "The test will pass if no OpenGL errors reported"; 3178 } 3179 3180 virtual long Setup() 3181 { 3182 glClear(GL_COLOR_BUFFER_BIT); 3183 return NO_ERROR; 3184 } 3185 3186 virtual long Run() 3187 { 3188 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 3189 if (!_program) 3190 { 3191 return ERROR; 3192 } 3193 glUseProgram(_program); 3194 3195 CColorArray coords; 3196 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 3197 3198 glGenVertexArrays(1, &_vao); 3199 glBindVertexArray(_vao); 3200 3201 glGenBuffers(1, &_buffer); 3202 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 3203 3204 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 3205 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 3206 glEnableVertexAttribArray(0); 3207 3208 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 3209 indirectElements.count = static_cast<GLuint>(coords.size()) / 2; 3210 indirectElements.primCount = 1; 3211 indirectElements.baseVertex = 0; 3212 indirectElements.firstIndex = static_cast<GLuint>(coords.size()) / 2; 3213 indirectElements.reservedMustBeZero = 0; 3214 3215 CElementArray elements(coords.size(), 0); 3216 for (size_t i = 0; i < elements.size(); ++i) 3217 { 3218 elements[i] = static_cast<GLuint>(i); 3219 } 3220 3221 glGenBuffers(1, &_bufferIndirect); 3222 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 3223 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW); 3224 3225 glGenBuffers(1, &_ebo); 3226 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 3227 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 3228 GL_STATIC_DRAW); 3229 3230 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0); 3231 3232 CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f)); 3233 CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f)); 3234 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 3235 3236 DIResult result; 3237 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]); 3238 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1, 3239 getWindowWidth(), getWindowHeight() / 2)); 3240 3241 ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]); 3242 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2, 3243 getWindowWidth(), getWindowHeight() / 2)); 3244 3245 return result.code(); 3246 } 3247 3248 virtual long Cleanup() 3249 { 3250 glDisableVertexAttribArray(0); 3251 glUseProgram(0); 3252 glDeleteProgram(_program); 3253 glDeleteVertexArrays(1, &_vao); 3254 glDeleteBuffers(1, &_buffer); 3255 glDeleteBuffers(1, &_ebo); 3256 glDeleteBuffers(1, &_bufferIndirect); 3257 return NO_ERROR; 3258 } 3259 3260private: 3261 GLuint _program; 3262 GLuint _vao, _buffer, _bufferIndirect, _ebo; 3263}; 3264 3265template <typename api> 3266class CBufferIndirectDrawElementsNoBasevertex : public DrawIndirectBase 3267{ 3268public: 3269 virtual std::string Title() 3270 { 3271 return "Indirect buffer glDrawElementsIndirect: non-zero base vertex"; 3272 } 3273 3274 virtual std::string Purpose() 3275 { 3276 return "Verify that it is possible to draw primitives with non-zero base vertex" NL "in indirect buffer"; 3277 } 3278 3279 virtual std::string Method() 3280 { 3281 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 3282 "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results"; 3283 } 3284 3285 virtual std::string PassCriteria() 3286 { 3287 return "The test will pass if no OpenGL errors reported"; 3288 } 3289 3290 virtual long Setup() 3291 { 3292 glClear(GL_COLOR_BUFFER_BIT); 3293 return NO_ERROR; 3294 } 3295 3296 virtual long Run() 3297 { 3298 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 3299 if (!_program) 3300 { 3301 return ERROR; 3302 } 3303 glUseProgram(_program); 3304 3305 CColorArray coords; 3306 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 3307 3308 glGenVertexArrays(1, &_vao); 3309 glBindVertexArray(_vao); 3310 3311 glGenBuffers(1, &_buffer); 3312 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 3313 3314 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 3315 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 3316 glEnableVertexAttribArray(0); 3317 3318 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 3319 indirectElements.count = static_cast<GLuint>(coords.size()) / 2; 3320 indirectElements.primCount = 1; 3321 indirectElements.baseVertex = static_cast<GLint>(coords.size()) / 2; 3322 indirectElements.firstIndex = 0; 3323 indirectElements.reservedMustBeZero = 0; 3324 3325 CElementArray elements(coords.size(), 0); 3326 for (size_t i = 0; i < elements.size(); ++i) 3327 { 3328 elements[i] = static_cast<GLuint>(i); 3329 } 3330 3331 glGenBuffers(1, &_bufferIndirect); 3332 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 3333 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW); 3334 3335 glGenBuffers(1, &_ebo); 3336 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 3337 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 3338 GL_STATIC_DRAW); 3339 3340 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0); 3341 3342 CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f)); 3343 CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f)); 3344 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 3345 3346 DIResult result; 3347 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]); 3348 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1, 3349 getWindowWidth(), getWindowHeight() / 2)); 3350 3351 ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]); 3352 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2, 3353 getWindowWidth(), getWindowHeight() / 2)); 3354 3355 return result.code(); 3356 } 3357 3358 virtual long Cleanup() 3359 { 3360 glDisableVertexAttribArray(0); 3361 glUseProgram(0); 3362 glDeleteProgram(_program); 3363 glDeleteVertexArrays(1, &_vao); 3364 glDeleteBuffers(1, &_buffer); 3365 glDeleteBuffers(1, &_ebo); 3366 glDeleteBuffers(1, &_bufferIndirect); 3367 return NO_ERROR; 3368 } 3369 3370private: 3371 GLuint _program; 3372 GLuint _vao, _buffer, _ebo, _bufferIndirect; 3373}; 3374 3375template <typename api> 3376class CBufferIndirectDrawElementsOffset : public DrawIndirectBase 3377{ 3378public: 3379 virtual std::string Title() 3380 { 3381 return "Indirect buffer glDrawElementsIndirect: offset as a function parameter"; 3382 } 3383 3384 virtual std::string Purpose() 3385 { 3386 return "Verify that it is possible to draw primitives with offset as a function parameter"; 3387 } 3388 3389 virtual std::string Method() 3390 { 3391 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 3392 "3. Draw primitives using glDrawElementsIndirect with offset" NL "4. Verify results"; 3393 } 3394 3395 virtual std::string PassCriteria() 3396 { 3397 return "The test will pass if no OpenGL errors reported"; 3398 } 3399 3400 virtual long Setup() 3401 { 3402 glClear(GL_COLOR_BUFFER_BIT); 3403 return NO_ERROR; 3404 } 3405 3406 virtual long Run() 3407 { 3408 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 3409 if (!_program) 3410 { 3411 return ERROR; 3412 } 3413 glUseProgram(_program); 3414 3415 CColorArray coords; 3416 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 3417 3418 glGenVertexArrays(1, &_vao); 3419 glBindVertexArray(_vao); 3420 3421 glGenBuffers(1, &_buffer); 3422 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 3423 3424 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 3425 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 3426 glEnableVertexAttribArray(0); 3427 3428 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 3429 indirectElements.count = static_cast<GLuint>(coords.size()); 3430 indirectElements.primCount = 1; 3431 indirectElements.baseVertex = 0; 3432 indirectElements.firstIndex = 0; 3433 indirectElements.reservedMustBeZero = 0; 3434 3435 CElementArray elements(coords.size(), 0); 3436 for (size_t i = 0; i < elements.size(); ++i) 3437 { 3438 elements[i] = static_cast<GLuint>(i); 3439 } 3440 3441 glGenBuffers(1, &_bufferIndirect); 3442 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 3443 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand) * 3, NULL, GL_STATIC_DRAW); 3444 glBufferSubData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), 3445 sizeof(DrawElementsIndirectCommand), &indirectElements); 3446 3447 glGenBuffers(1, &_ebo); 3448 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 3449 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 3450 GL_STATIC_DRAW); 3451 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (void*)sizeof(DrawElementsIndirectCommand)); 3452 3453 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f)); 3454 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 3455 3456 DIResult result; 3457 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 3458 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 3459 getWindowHeight())); 3460 3461 return result.code(); 3462 } 3463 3464 virtual long Cleanup() 3465 { 3466 glDisableVertexAttribArray(0); 3467 glUseProgram(0); 3468 glDeleteProgram(_program); 3469 glDeleteVertexArrays(1, &_vao); 3470 glDeleteBuffers(1, &_buffer); 3471 glDeleteBuffers(1, &_ebo); 3472 glDeleteBuffers(1, &_bufferIndirect); 3473 return NO_ERROR; 3474 } 3475 3476private: 3477 GLuint _program; 3478 GLuint _vao, _buffer, _ebo, _bufferIndirect; 3479}; 3480 3481class CBasicVertexIDsDef : public DrawIndirectBase 3482{ 3483public: 3484 virtual long Setup() 3485 { 3486 glClear(GL_COLOR_BUFFER_BIT); 3487 return NO_ERROR; 3488 } 3489 3490 template <typename api> 3491 long Run() 3492 { 3493 CColorArray coords; 3494 PrimitiveGen(GL_TRIANGLES, _drawSizeX, _drawSizeY, coords); 3495 3496 CColorArray coords_instanced(4); 3497 coords_instanced[0] = tcu::Vec4(0.5, 0.5, 0.0, 0.0); 3498 coords_instanced[1] = tcu::Vec4(-0.5, 0.5, 0.0, 0.0); 3499 coords_instanced[2] = tcu::Vec4(-0.5, -0.5, 0.0, 0.0); 3500 coords_instanced[3] = tcu::Vec4(0.5, -0.5, 0.0, 0.0); 3501 3502 std::vector<glw::GLfloat> ref_VertexId(coords.size()); 3503 for (size_t i = 0; i < ref_VertexId.size(); i++) 3504 { 3505 ref_VertexId[i] = glw::GLfloat(i); 3506 } 3507 3508 std::vector<glw::GLfloat> ref_InstanceId(4); 3509 for (size_t i = 0; i < ref_InstanceId.size(); i++) 3510 { 3511 ref_InstanceId[i] = glw::GLfloat(i); 3512 } 3513 3514 _program = CreateProgram(Vsh<api>(), "", Fsh<api>(), true); 3515 if (!_program) 3516 { 3517 return ERROR; 3518 } 3519 glUseProgram(_program); 3520 3521 glGenBuffers(1, &_vbo); 3522 glBindBuffer(GL_ARRAY_BUFFER, _vbo); 3523 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0]) + 3524 coords_instanced.size() * sizeof(coords_instanced[0]) + 3525 ref_VertexId.size() * sizeof(ref_VertexId[0]) + 3526 ref_InstanceId.size() * sizeof(ref_InstanceId[0])), 3527 NULL, GL_STATIC_DRAW); 3528 3529 const size_t coords_offset = 0; 3530 const size_t coords_instanced_offset = coords_offset + coords.size() * sizeof(coords[0]); 3531 const size_t ref_VertexId_offset = 3532 coords_instanced_offset + coords_instanced.size() * sizeof(coords_instanced[0]); 3533 const size_t ref_InstanceId_offset = ref_VertexId_offset + ref_VertexId.size() * sizeof(ref_VertexId[0]); 3534 3535 glBufferSubData(GL_ARRAY_BUFFER, coords_offset, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0]); 3536 glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)coords_instanced_offset, 3537 (GLsizeiptr)(coords_instanced.size() * sizeof(coords_instanced[0])), &coords_instanced[0]); 3538 glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)ref_VertexId_offset, 3539 (GLsizeiptr)(ref_VertexId.size() * sizeof(ref_VertexId[0])), &ref_VertexId[0]); 3540 glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)ref_InstanceId_offset, 3541 (GLsizeiptr)(ref_InstanceId.size() * sizeof(ref_InstanceId[0])), &ref_InstanceId[0]); 3542 3543 glGenVertexArrays(1, &_vao); 3544 glBindVertexArray(_vao); 3545 3546 //i_vertex (coords) 3547 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid*>(coords_offset)); 3548 glEnableVertexAttribArray(0); 3549 3550 //i_vertex_instanced (coords_instanced) 3551 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid*>(coords_instanced_offset)); 3552 glEnableVertexAttribArray(1); 3553 glVertexAttribDivisor(1, 1); 3554 3555 //i_ref_VertexId 3556 glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid*>(ref_VertexId_offset)); 3557 glEnableVertexAttribArray(2); 3558 //i_ref_InstanceId 3559 glVertexAttribPointer(3, 1, GL_FLOAT, GL_FALSE, 0, reinterpret_cast<glw::GLvoid*>(ref_InstanceId_offset)); 3560 glEnableVertexAttribArray(3); 3561 glVertexAttribDivisor(3, 1); 3562 3563 DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 }; 3564 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 3565 3566 CElementArray elements(coords.size(), 0); 3567 for (size_t i = 0; i < elements.size(); ++i) 3568 { 3569 elements[i] = static_cast<GLuint>(i); 3570 } 3571 3572 switch (_drawFunc) 3573 { 3574 case DRAW_ARRAYS: 3575 { 3576 indirectArrays.count = static_cast<GLuint>(coords.size()); 3577 indirectArrays.primCount = 4; 3578 indirectArrays.first = 0; 3579 indirectArrays.reservedMustBeZero = 0; 3580 3581 { 3582 GLuint buffer; 3583 glGenBuffers(1, &buffer); 3584 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer); 3585 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectArrays), &indirectArrays, GL_STATIC_DRAW); 3586 glDrawArraysIndirect(GL_TRIANGLES, 0); 3587 glDeleteBuffers(1, &buffer); 3588 } 3589 } 3590 break; 3591 case DRAW_ELEMENTS: 3592 { 3593 indirectElements.count = static_cast<GLuint>(coords.size()); 3594 indirectElements.primCount = 4; 3595 indirectElements.firstIndex = 0; 3596 indirectElements.baseVertex = 0; 3597 indirectElements.reservedMustBeZero = 0; 3598 3599 glGenBuffers(1, &_ebo); 3600 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 3601 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 3602 GL_STATIC_DRAW); 3603 3604 { 3605 GLuint buffer; 3606 glGenBuffers(1, &buffer); 3607 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, buffer); 3608 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(indirectElements), &indirectElements, GL_STATIC_DRAW); 3609 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0); 3610 glDeleteBuffers(1, &buffer); 3611 } 3612 } 3613 break; 3614 default: 3615 throw std::runtime_error("Unknown draw function!"); 3616 break; 3617 } 3618 3619 CColorArray bufferRef1(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.5f, 0.0f)); 3620 CColorArray bufferRef2(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.75f, 0.0f)); 3621 CColorArray bufferRef3(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.25f, 0.0f)); 3622 CColorArray bufferRef4(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f, 1.0f, 0.0f, 0.0f)); 3623 3624 CColorArray bufferTest(getWindowWidth() / 2 * getWindowHeight() / 2, tcu::Vec4(0.0f)); 3625 DIResult result; 3626 3627 ReadPixelsFloat<api>(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, &bufferTest[0]); 3628 result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef1, 3629 getWindowWidth() / 2, getWindowHeight() / 2)); 3630 3631 ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, 0, getWindowWidth() / 2, getWindowHeight() / 2, 3632 &bufferTest[0]); 3633 result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef2, 3634 getWindowWidth() / 2, getWindowHeight() / 2)); 3635 3636 ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth() / 2, getWindowHeight() / 2, 3637 &bufferTest[0]); 3638 result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef3, 3639 getWindowWidth() / 2, getWindowHeight() / 2)); 3640 3641 ReadPixelsFloat<api>((getWindowWidth() + 1) / 2, (getWindowHeight() + 1) / 2, getWindowWidth() / 2, 3642 getWindowHeight() / 2, &bufferTest[0]); 3643 result.sub_result(BuffersCompare(bufferTest, getWindowWidth() / 2, getWindowHeight() / 2, bufferRef4, 3644 getWindowWidth() / 2, getWindowHeight() / 2)); 3645 3646 return result.code(); 3647 } 3648 3649 virtual long Cleanup() 3650 { 3651 glDisableVertexAttribArray(0); 3652 glBindBuffer(GL_ARRAY_BUFFER, 0); 3653 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 3654 glBindVertexArray(0); 3655 glUseProgram(0); 3656 3657 if (_vao) 3658 { 3659 glDeleteVertexArrays(1, &_vao); 3660 } 3661 if (_vbo) 3662 { 3663 glDeleteBuffers(1, &_vbo); 3664 } 3665 if (_ebo) 3666 { 3667 glDeleteBuffers(1, &_ebo); 3668 } 3669 if (_program) 3670 { 3671 glDeleteProgram(_program); 3672 } 3673 3674 return NO_ERROR; 3675 } 3676 3677 template <typename api> 3678 std::string Vsh() 3679 { 3680 return api::glslVer() + NL 3681 "layout(location = 0) in vec4 i_vertex;" NL "layout(location = 1) in vec4 i_vertex_instanced;" NL 3682 "layout(location = 2) in float i_ref_VertexId;" NL "layout(location = 3) in float i_ref_InstanceId;" NL 3683 "out vec4 val_Result;" NL "void main()" NL "{" NL 3684 " gl_Position = vec4(i_vertex.xyz * .5, 1.0) + i_vertex_instanced;" NL 3685 " if ( gl_VertexID == int(i_ref_VertexId + .5) && gl_InstanceID == int(i_ref_InstanceId + .5)) {" NL 3686 " val_Result = vec4(0.0, 1.0, float(gl_InstanceID) / 4.0, 1.0);" NL " } else {" NL 3687 " val_Result = vec4(1.0, 0.0, 0.0, 1.0);" NL " }" NL "}"; 3688 } 3689 3690 template <typename api> 3691 std::string Fsh() 3692 { 3693 return api::glslVer() + NL "precision highp float; " NL "in vec4 val_Result;" NL "out vec4 outColor;" NL 3694 "void main() {" NL " outColor = val_Result;" NL "}"; 3695 } 3696 3697 CBasicVertexIDsDef(TDrawFunction drawFunc) 3698 : _drawFunc(drawFunc), _drawSizeX(2), _drawSizeY(2), _vao(0), _vbo(0), _ebo(0), _program(0) 3699 { 3700 } 3701 3702private: 3703 TDrawFunction _drawFunc; 3704 unsigned int _drawSizeX; 3705 unsigned int _drawSizeY; 3706 3707 GLuint _vao; 3708 GLuint _vbo, _ebo; 3709 GLuint _program; 3710 3711 CBasicVertexIDsDef() 3712 { 3713 } 3714}; 3715 3716template <typename api> 3717class CBufferIndirectDrawArraysVertexIds : public CBasicVertexIDsDef 3718{ 3719public: 3720 virtual std::string Title() 3721 { 3722 return "Indirect buffer glDrawArraysIndirect: all non-zero arguments, verify vertex ids"; 3723 } 3724 3725 virtual std::string Purpose() 3726 { 3727 return "Verify that it is possible to draw primitives with all non-zero arguments" NL "in indirect buffer"; 3728 } 3729 3730 virtual std::string Method() 3731 { 3732 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 3733 "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results"; 3734 } 3735 3736 virtual std::string PassCriteria() 3737 { 3738 return "The test will pass if no OpenGL errors reported"; 3739 } 3740 3741 virtual long Run() 3742 { 3743 return CBasicVertexIDsDef::Run<api>(); 3744 } 3745 3746 CBufferIndirectDrawArraysVertexIds() : CBasicVertexIDsDef(DRAW_ARRAYS) 3747 { 3748 } 3749}; 3750 3751template <typename api> 3752class CBufferIndirectDrawElementsVertexIds : public CBasicVertexIDsDef 3753{ 3754public: 3755 virtual std::string Title() 3756 { 3757 return "Indirect buffer glDrawElementsIndirect: all non-zero arguments, verify vertex ids"; 3758 } 3759 3760 virtual std::string Purpose() 3761 { 3762 return "Verify that it is possible to draw primitives with all non-zero arguments" NL "in indirect buffer"; 3763 } 3764 3765 virtual std::string Method() 3766 { 3767 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 3768 "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results"; 3769 } 3770 3771 virtual std::string PassCriteria() 3772 { 3773 return "The test will pass if no OpenGL errors reported"; 3774 } 3775 3776 virtual long Run() 3777 { 3778 return CBasicVertexIDsDef::Run<api>(); 3779 } 3780 3781 CBufferIndirectDrawElementsVertexIds() : CBasicVertexIDsDef(DRAW_ELEMENTS) 3782 { 3783 } 3784}; 3785 3786template <typename api> 3787class CIndicesDataTypeUnsignedShort : public DrawIndirectBase 3788{ 3789public: 3790 virtual std::string Title() 3791 { 3792 return "glDrawElementsIndirect indices data type: unsigned short"; 3793 } 3794 3795 virtual std::string Purpose() 3796 { 3797 return "Verify that unsigned short indices are accepted by glDrawElementsIndirect"; 3798 } 3799 3800 virtual std::string Method() 3801 { 3802 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL "3. Create element buffer" NL 3803 "4. Draw primitives using glDrawElementsIndirect" NL "5. Verify results"; 3804 } 3805 3806 virtual std::string PassCriteria() 3807 { 3808 return "The test will pass if no OpenGL errors reported"; 3809 } 3810 3811 virtual long Setup() 3812 { 3813 glClear(GL_COLOR_BUFFER_BIT); 3814 return NO_ERROR; 3815 } 3816 3817 virtual long Run() 3818 { 3819 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 3820 if (!_program) 3821 { 3822 return ERROR; 3823 } 3824 glUseProgram(_program); 3825 3826 CColorArray coords; 3827 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 3828 3829 glGenVertexArrays(1, &_vao); 3830 glBindVertexArray(_vao); 3831 3832 glGenBuffers(1, &_buffer); 3833 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 3834 3835 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 3836 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 3837 glEnableVertexAttribArray(0); 3838 3839 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 3840 indirectElements.count = static_cast<GLuint>(coords.size()) / 2; 3841 indirectElements.primCount = 1; 3842 indirectElements.baseVertex = -static_cast<GLint>(coords.size()) / 4; 3843 indirectElements.firstIndex = static_cast<GLuint>(coords.size()) / 4; 3844 indirectElements.reservedMustBeZero = 0; 3845 3846 std::vector<GLushort> elements(coords.size(), 0); 3847 for (size_t i = 0; i < elements.size(); ++i) 3848 { 3849 elements[i] = static_cast<GLushort>(i); 3850 } 3851 3852 glGenBuffers(1, &_bufferIndirect); 3853 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 3854 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), NULL, GL_STATIC_DRAW); 3855 glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), &indirectElements); 3856 3857 glGenBuffers(1, &_ebo); 3858 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 3859 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 3860 GL_STATIC_DRAW); 3861 3862 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT, 0); 3863 3864 CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f)); 3865 CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f)); 3866 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 3867 3868 DIResult result; 3869 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]); 3870 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2, 3871 getWindowWidth(), getWindowHeight() / 2)); 3872 3873 ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]); 3874 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1, 3875 getWindowWidth(), getWindowHeight() / 2)); 3876 3877 return result.code(); 3878 } 3879 3880 virtual long Cleanup() 3881 { 3882 glDisableVertexAttribArray(0); 3883 glUseProgram(0); 3884 glDeleteProgram(_program); 3885 glDeleteVertexArrays(1, &_vao); 3886 glDeleteBuffers(1, &_buffer); 3887 glDeleteBuffers(1, &_ebo); 3888 glDeleteBuffers(1, &_bufferIndirect); 3889 return NO_ERROR; 3890 } 3891 3892private: 3893 GLuint _program; 3894 GLuint _vao, _buffer, _ebo, _bufferIndirect; 3895}; 3896 3897template <typename api> 3898class CIndicesDataTypeUnsignedByte : public DrawIndirectBase 3899{ 3900public: 3901 virtual std::string Title() 3902 { 3903 return "glDrawElementsIndirect indices data type: unsigned byte"; 3904 } 3905 3906 virtual std::string Purpose() 3907 { 3908 return "Verify that unsigned byte indices are accepted by glDrawElementsIndirect"; 3909 } 3910 3911 virtual std::string Method() 3912 { 3913 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL "3. Create element buffer" NL 3914 "4. Draw primitives using glDrawElementsIndirect" NL "5. Verify results"; 3915 } 3916 3917 virtual std::string PassCriteria() 3918 { 3919 return "The test will pass if no OpenGL errors reported"; 3920 } 3921 3922 virtual long Setup() 3923 { 3924 glClear(GL_COLOR_BUFFER_BIT); 3925 return NO_ERROR; 3926 } 3927 3928 virtual long Run() 3929 { 3930 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 3931 if (!_program) 3932 { 3933 return ERROR; 3934 } 3935 glUseProgram(_program); 3936 3937 CColorArray coords; 3938 PrimitiveGen(GL_TRIANGLES, 2, 2, coords); 3939 3940 glGenVertexArrays(1, &_vao); 3941 glBindVertexArray(_vao); 3942 3943 glGenBuffers(1, &_buffer); 3944 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 3945 3946 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 3947 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 3948 glEnableVertexAttribArray(0); 3949 3950 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 3951 indirectElements.count = static_cast<GLuint>(coords.size()) / 2; 3952 indirectElements.primCount = 1; 3953 indirectElements.baseVertex = -static_cast<GLint>(coords.size()) / 4; 3954 indirectElements.firstIndex = static_cast<GLuint>(coords.size()) / 4; 3955 indirectElements.reservedMustBeZero = 0; 3956 3957 std::vector<GLubyte> elements(coords.size(), 0); 3958 for (size_t i = 0; i < elements.size(); ++i) 3959 { 3960 elements[i] = static_cast<GLubyte>(i); 3961 } 3962 3963 glGenBuffers(1, &_bufferIndirect); 3964 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 3965 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), NULL, GL_STATIC_DRAW); 3966 glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), &indirectElements); 3967 3968 glGenBuffers(1, &_ebo); 3969 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 3970 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 3971 GL_STATIC_DRAW); 3972 3973 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_BYTE, 0); 3974 3975 CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f)); 3976 CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f)); 3977 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 3978 3979 DIResult result; 3980 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]); 3981 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef2, 3982 getWindowWidth(), getWindowHeight() / 2)); 3983 3984 ReadPixelsFloat<api>(0, (getWindowHeight() + 1) / 2, getWindowWidth(), getWindowHeight() / 2, &bufferTest[0]); 3985 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight() / 2, bufferRef1, 3986 getWindowWidth(), getWindowHeight() / 2)); 3987 3988 return result.code(); 3989 } 3990 3991 virtual long Cleanup() 3992 { 3993 glDisableVertexAttribArray(0); 3994 glUseProgram(0); 3995 glDeleteProgram(_program); 3996 glDeleteVertexArrays(1, &_vao); 3997 glDeleteBuffers(1, &_buffer); 3998 glDeleteBuffers(1, &_ebo); 3999 glDeleteBuffers(1, &_bufferIndirect); 4000 return NO_ERROR; 4001 } 4002 4003private: 4004 GLuint _program; 4005 GLuint _vao, _buffer, _ebo, _bufferIndirect; 4006}; 4007 4008class CPrimitiveMode : public DrawIndirectBase 4009{ 4010public: 4011 template <typename api> 4012 bool IsGeometryShaderSupported() 4013 { 4014 if (api::isES()) 4015 { 4016 const glu::ContextInfo& info = m_context.getContextInfo(); 4017 const glu::ContextType& type = m_context.getRenderContext().getType(); 4018 4019 /* ES 3.2+ included geometry shaders into the core */ 4020 if (glu::contextSupports(type, glu::ApiType(3, 2, glu::PROFILE_ES))) 4021 { 4022 return true; 4023 } 4024 /* ES 3.1 may be able to support geometry shaders via extensions */ 4025 else if ((glu::contextSupports(type, glu::ApiType(3, 1, glu::PROFILE_ES))) && 4026 ((true == info.isExtensionSupported("GL_EXT_geometry_shader")) || 4027 (true == info.isExtensionSupported("GL_OES_geometry_shader")))) 4028 { 4029 return true; 4030 } 4031 else 4032 { 4033 OutputNotSupported("Geometry shader is not supported\n"); 4034 return false; 4035 } 4036 } 4037 else 4038 { 4039 return true; 4040 } 4041 } 4042 virtual long Setup() 4043 { 4044 _sizeX = getWindowWidth(); 4045 _sizeY = getWindowHeight(); 4046 if (_primitiveType != GL_TRIANGLE_STRIP && _primitiveType != GL_TRIANGLE_STRIP_ADJACENCY && 4047 _primitiveType != GL_TRIANGLES && _primitiveType != GL_TRIANGLES_ADJACENCY && 4048 _primitiveType != GL_TRIANGLE_FAN) 4049 { 4050 _sizeX &= (-4); 4051 _sizeY &= (-4); 4052 } 4053 if ((int)_drawSizeX < 0 || (int)_drawSizeY < 0) 4054 { 4055 //no PrimitiveGen dimensions given. assume same dimensions as rendered image^ 4056 _drawSizeX = _sizeX; 4057 _drawSizeY = _sizeY; 4058 if (_primitiveType == GL_POINTS) 4059 { 4060 //clamp vertex number (and rendering size) for points to max. 10000 4061 _sizeX = _drawSizeX = std::min(_drawSizeX, 100u); 4062 _sizeY = _drawSizeY = std::min(_drawSizeY, 100u); 4063 } 4064 } 4065 4066 glClear(GL_COLOR_BUFFER_BIT); 4067 return NO_ERROR; 4068 } 4069 4070 template <typename api> 4071 long Run(bool pointMode = false) 4072 { 4073 4074 glClear(GL_COLOR_BUFFER_BIT); 4075 4076 _program = CreateProgram(pointMode ? shaders::vshSimple_point<api>() : shaders::vshSimple<api>(), "", 4077 shaders::fshSimple<api>(), true); 4078 if (!_program) 4079 { 4080 return ERROR; 4081 } 4082 glUseProgram(_program); 4083 4084 CColorArray coords; 4085 PrimitiveGen(_primitiveType, _drawSizeX, _drawSizeY, coords); 4086 4087 glGenVertexArrays(1, &_vao); 4088 glBindVertexArray(_vao); 4089 4090 glGenBuffers(1, &_buffer); 4091 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 4092 4093 CColorArray padding(10, tcu::Vec4(0.0f)); 4094 4095 glBufferData(GL_ARRAY_BUFFER, 4096 (GLsizeiptr)(coords.size() * (sizeof(coords[0])) + padding.size() * (sizeof(padding[0]))), NULL, 4097 GL_STREAM_DRAW); 4098 glBufferSubData(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(padding.size() * (sizeof(padding[0]))), &padding[0]); 4099 glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)(padding.size() * (sizeof(padding[0]))), 4100 (GLsizeiptr)(coords.size() * (sizeof(coords[0]))), &coords[0]); 4101 4102 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 4103 glEnableVertexAttribArray(0); 4104 4105 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 4106 DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 }; 4107 4108 CElementArray elements(coords.size(), 0); 4109 for (size_t i = 0; i < elements.size(); ++i) 4110 { 4111 elements[i] = static_cast<GLuint>(i); 4112 } 4113 4114 glGenBuffers(1, &_bufferIndirect); 4115 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 4116 4117 switch (_drawFunc) 4118 { 4119 case DRAW_ARRAYS: 4120 { 4121 indirectArrays.count = static_cast<GLuint>(coords.size()) / 2; 4122 indirectArrays.primCount = 1; 4123 indirectArrays.first = 10; 4124 indirectArrays.reservedMustBeZero = 0; 4125 4126 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), NULL, GL_STATIC_DRAW); 4127 glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawArraysIndirectCommand), &indirectArrays); 4128 4129 glDrawArraysIndirect(_primitiveType, 0); 4130 } 4131 break; 4132 case DRAW_ELEMENTS: 4133 { 4134 indirectElements.count = static_cast<GLuint>(coords.size()) / 2; 4135 indirectElements.primCount = 1; 4136 indirectElements.baseVertex = 7; 4137 indirectElements.firstIndex = 3; 4138 indirectElements.reservedMustBeZero = 0; 4139 4140 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), NULL, GL_STATIC_DRAW); 4141 glBufferSubData(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), &indirectElements); 4142 4143 glGenBuffers(1, &_ebo); 4144 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 4145 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 4146 GL_STATIC_DRAW); 4147 4148 glDrawElementsIndirect(_primitiveType, GL_UNSIGNED_INT, 0); 4149 } 4150 break; 4151 default: 4152 throw std::runtime_error("Unknown draw function!"); 4153 break; 4154 } 4155 4156 CColorArray bufferRef1(_sizeX * _sizeY / 2, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f)); 4157 CColorArray bufferRef2(_sizeX * _sizeY / 2, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f)); 4158 CColorArray bufferTest(_sizeX * _sizeY, tcu::Vec4(0.0f)); 4159 4160 DIResult result; 4161 ReadPixelsFloat<api>(0, (_sizeY + 1) / 2, _sizeX, _sizeY / 2, &bufferTest[0]); 4162 result.sub_result(BuffersCompare(bufferTest, _sizeX, _sizeY / 2, bufferRef1, _sizeX, _sizeY / 2)); 4163 4164 switch (_primitiveType) 4165 { 4166 case GL_TRIANGLES_ADJACENCY: 4167 case GL_TRIANGLE_STRIP_ADJACENCY: 4168 { 4169 CColorArray bufferRef3(_sizeX * _sizeY / 16, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f)); 4170 CColorArray bufferRef4(_sizeX * _sizeY / 8, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f)); 4171 CColorArray bufferRef5(_sizeX * _sizeY / 4, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f)); 4172 4173 CColorArray bufferTest3(_sizeX * _sizeY / 16, tcu::Vec4(0.0f)); 4174 CColorArray bufferTest4(_sizeX * _sizeY / 8, tcu::Vec4(0.0f)); 4175 CColorArray bufferTest5(_sizeX * _sizeY / 4, tcu::Vec4(0.0f)); 4176 4177 ReadPixelsFloat<api>(0, (_sizeY + 3) / 4, _sizeX / 4, _sizeY / 4, &bufferTest3[0]); 4178 result.sub_result(BuffersCompare(bufferTest3, _sizeX / 4, _sizeY / 4, bufferRef3, _sizeX / 4, _sizeY / 4)); 4179 4180 ReadPixelsFloat<api>((_sizeX + 3) / 4, (_sizeY + 3) / 4, _sizeX / 2, _sizeY / 4, &bufferTest4[0]); 4181 result.sub_result(BuffersCompare(bufferTest4, _sizeX / 2, _sizeY / 4, bufferRef4, _sizeX / 2, _sizeY / 4)); 4182 4183 ReadPixelsFloat<api>((_sizeX * 3 + 3) / 4, (_sizeY + 3) / 4, _sizeX / 4, _sizeY / 4, &bufferTest3[0]); 4184 result.sub_result(BuffersCompare(bufferTest3, _sizeX / 4, _sizeY / 4, bufferRef3, _sizeX / 4, _sizeY / 4)); 4185 4186 ReadPixelsFloat<api>(0, 0, _sizeX, _sizeY / 4, &bufferTest5[0]); 4187 result.sub_result(BuffersCompare(bufferTest5, _sizeX, _sizeY / 4, bufferRef5, _sizeX, _sizeY / 4)); 4188 } 4189 break; 4190 default: 4191 { 4192 ReadPixelsFloat<api>(0, 0, _sizeX, _sizeY / 2, &bufferTest[0]); 4193 result.sub_result(BuffersCompare(bufferTest, _sizeX, _sizeY / 2, bufferRef2, _sizeX, _sizeY / 2)); 4194 } 4195 break; 4196 } 4197 4198 return result.code(); 4199 } 4200 4201 virtual long Cleanup() 4202 { 4203 glDisableVertexAttribArray(0); 4204 glUseProgram(0); 4205 glDeleteProgram(_program); 4206 glDeleteVertexArrays(1, &_vao); 4207 glDeleteBuffers(1, &_buffer); 4208 glDeleteBuffers(1, &_ebo); 4209 glDeleteBuffers(1, &_bufferIndirect); 4210 return NO_ERROR; 4211 } 4212 4213 CPrimitiveMode(TDrawFunction drawFunc, GLenum primitiveType, unsigned int sizeX = -1, unsigned sizeY = -1) 4214 : _drawFunc(drawFunc) 4215 , _primitiveType(primitiveType) 4216 , _drawSizeX(sizeX) 4217 , _drawSizeY(sizeY) 4218 , _sizeX(0) 4219 , _sizeY(0) 4220 , _program(0) 4221 , _vao(0) 4222 , _buffer(0) 4223 , _ebo(0) 4224 , _bufferIndirect(0) 4225 { 4226 } 4227 4228private: 4229 TDrawFunction _drawFunc; 4230 GLenum _primitiveType; 4231 unsigned int _drawSizeX, _drawSizeY; //dims for primitive generator 4232 unsigned int _sizeX, _sizeY; //rendering size 4233 GLuint _program; 4234 GLuint _vao, _buffer, _ebo, _bufferIndirect; 4235 4236 CPrimitiveMode(); 4237}; 4238 4239template <typename api> 4240class CModeDrawArraysPoints : public CPrimitiveMode 4241{ 4242public: 4243 virtual std::string Title() 4244 { 4245 return "glDrawArraysIndirect mode: GL_POINTS"; 4246 } 4247 4248 virtual std::string Purpose() 4249 { 4250 return "Verify that glDrawArraysIndirect with GL_POINTS works correctly"; 4251 } 4252 4253 virtual std::string Method() 4254 { 4255 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4256 "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results"; 4257 } 4258 4259 virtual std::string PassCriteria() 4260 { 4261 return "The test will pass if no OpenGL errors reported"; 4262 } 4263 4264 CModeDrawArraysPoints() : CPrimitiveMode(DRAW_ARRAYS, GL_POINTS) 4265 { 4266 } 4267 4268 virtual long Run() 4269 { 4270 return CPrimitiveMode::Run<api>(true); 4271 } 4272}; 4273 4274template <typename api> 4275class CModeDrawArraysLines : public CPrimitiveMode 4276{ 4277public: 4278 virtual std::string Title() 4279 { 4280 return "glDrawArraysIndirect mode: GL_LINES"; 4281 } 4282 4283 virtual std::string Purpose() 4284 { 4285 return "Verify that glDrawArraysIndirect with GL_LINES works correctly"; 4286 } 4287 4288 virtual std::string Method() 4289 { 4290 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4291 "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results"; 4292 } 4293 4294 virtual std::string PassCriteria() 4295 { 4296 return "The test will pass if no OpenGL errors reported"; 4297 } 4298 4299 CModeDrawArraysLines() : CPrimitiveMode(DRAW_ARRAYS, GL_LINES) 4300 { 4301 } 4302 4303 virtual long Run() 4304 { 4305 return CPrimitiveMode::Run<api>(); 4306 } 4307}; 4308 4309template <typename api> 4310class CModeDrawArraysLineStrip : public CPrimitiveMode 4311{ 4312public: 4313 virtual std::string Title() 4314 { 4315 return "glDrawArraysIndirect mode: GL_LINE_STRIP"; 4316 } 4317 4318 virtual std::string Purpose() 4319 { 4320 return "Verify that glDrawArraysIndirect with GL_LINE_STRIP works correctly"; 4321 } 4322 4323 virtual std::string Method() 4324 { 4325 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4326 "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results"; 4327 } 4328 4329 virtual std::string PassCriteria() 4330 { 4331 return "The test will pass if no OpenGL errors reported"; 4332 } 4333 4334 CModeDrawArraysLineStrip() : CPrimitiveMode(DRAW_ARRAYS, GL_LINE_STRIP) 4335 { 4336 } 4337 virtual long Run() 4338 { 4339 return CPrimitiveMode::Run<api>(); 4340 } 4341}; 4342 4343template <typename api> 4344class CModeDrawArraysLineLoop : public CPrimitiveMode 4345{ 4346public: 4347 virtual std::string Title() 4348 { 4349 return "glDrawArraysIndirect mode: GL_LINE_LOOP"; 4350 } 4351 4352 virtual std::string Purpose() 4353 { 4354 return "Verify that glDrawArraysIndirect with GL_LINE_LOOP works correctly"; 4355 } 4356 4357 virtual std::string Method() 4358 { 4359 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4360 "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results"; 4361 } 4362 4363 virtual std::string PassCriteria() 4364 { 4365 return "The test will pass if no OpenGL errors reported"; 4366 } 4367 4368 CModeDrawArraysLineLoop() : CPrimitiveMode(DRAW_ARRAYS, GL_LINE_LOOP) 4369 { 4370 } 4371 4372 virtual long Run() 4373 { 4374 return CPrimitiveMode::Run<api>(); 4375 } 4376}; 4377 4378template <typename api> 4379class CModeDrawArraysTriangleStrip : public CPrimitiveMode 4380{ 4381public: 4382 virtual std::string Title() 4383 { 4384 return "glDrawArraysIndirect mode: GL_TRIANGLE_STRIP"; 4385 } 4386 4387 virtual std::string Purpose() 4388 { 4389 return "Verify that glDrawArraysIndirect with GL_TRIANGLE_STRIP works correctly"; 4390 } 4391 4392 virtual std::string Method() 4393 { 4394 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4395 "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results"; 4396 } 4397 4398 virtual std::string PassCriteria() 4399 { 4400 return "The test will pass if no OpenGL errors reported"; 4401 } 4402 4403 CModeDrawArraysTriangleStrip() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLE_STRIP, 2, 2) 4404 { 4405 } 4406 4407 virtual long Run() 4408 { 4409 return CPrimitiveMode::Run<api>(); 4410 } 4411}; 4412 4413template <typename api> 4414class CModeDrawArraysTriangleFan : public CPrimitiveMode 4415{ 4416public: 4417 virtual std::string Title() 4418 { 4419 return "glDrawArraysIndirect mode: GL_TRIANGLE_FAN"; 4420 } 4421 4422 virtual std::string Purpose() 4423 { 4424 return "Verify that glDrawArraysIndirect with GL_TRIANGLE_FAN works correctly"; 4425 } 4426 4427 virtual std::string Method() 4428 { 4429 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4430 "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results"; 4431 } 4432 4433 virtual std::string PassCriteria() 4434 { 4435 return "The test will pass if no OpenGL errors reported"; 4436 } 4437 4438 CModeDrawArraysTriangleFan() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLE_FAN, 2, 2) 4439 { 4440 } 4441 4442 virtual long Run() 4443 { 4444 return CPrimitiveMode::Run<api>(); 4445 } 4446}; 4447 4448template <typename api> 4449class CModeDrawArraysLinesAdjacency : public CPrimitiveMode 4450{ 4451public: 4452 virtual std::string Title() 4453 { 4454 return "glDrawArraysIndirect mode: GL_LINES_ADJACENCY"; 4455 } 4456 4457 virtual std::string Purpose() 4458 { 4459 return "Verify that glDrawArraysIndirect with GL_LINES_ADJACENCY works correctly"; 4460 } 4461 4462 virtual std::string Method() 4463 { 4464 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4465 "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results"; 4466 } 4467 4468 virtual std::string PassCriteria() 4469 { 4470 return "The test will pass if no OpenGL errors reported"; 4471 } 4472 4473 CModeDrawArraysLinesAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_LINES_ADJACENCY) 4474 { 4475 } 4476 4477 virtual long Run() 4478 { 4479 if (!IsGeometryShaderSupported<api>()) 4480 return NOT_SUPPORTED; 4481 return CPrimitiveMode::Run<api>(); 4482 } 4483}; 4484 4485template <typename api> 4486class CModeDrawArraysLineStripAdjacency : public CPrimitiveMode 4487{ 4488public: 4489 virtual std::string Title() 4490 { 4491 return "glDrawArraysIndirect mode: GL_LINE_STRIP_ADJACENCY"; 4492 } 4493 4494 virtual std::string Purpose() 4495 { 4496 return "Verify that glDrawArraysIndirect with GL_LINE_STRIP_ADJACENCY works correctly"; 4497 } 4498 4499 virtual std::string Method() 4500 { 4501 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4502 "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results"; 4503 } 4504 4505 virtual std::string PassCriteria() 4506 { 4507 return "The test will pass if no OpenGL errors reported"; 4508 } 4509 4510 CModeDrawArraysLineStripAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_LINE_STRIP_ADJACENCY) 4511 { 4512 } 4513 4514 virtual long Run() 4515 { 4516 if (!IsGeometryShaderSupported<api>()) 4517 return NOT_SUPPORTED; 4518 return CPrimitiveMode::Run<api>(); 4519 } 4520}; 4521 4522template <typename api> 4523class CModeDrawArraysTrianglesAdjacency : public CPrimitiveMode 4524{ 4525public: 4526 virtual std::string Title() 4527 { 4528 return "glDrawArraysIndirect mode: GL_TRIANGLES_ADJACENCY"; 4529 } 4530 4531 virtual std::string Purpose() 4532 { 4533 return "Verify that glDrawArraysIndirect with GL_TRIANGLES_ADJACENCY works correctly"; 4534 } 4535 4536 virtual std::string Method() 4537 { 4538 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4539 "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results"; 4540 } 4541 4542 virtual std::string PassCriteria() 4543 { 4544 return "The test will pass if no OpenGL errors reported"; 4545 } 4546 4547 CModeDrawArraysTrianglesAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLES_ADJACENCY, 4, 4) 4548 { 4549 } 4550 4551 virtual long Run() 4552 { 4553 if (!IsGeometryShaderSupported<api>()) 4554 return NOT_SUPPORTED; 4555 return CPrimitiveMode::Run<api>(); 4556 } 4557}; 4558 4559template <typename api> 4560class CModeDrawArraysTriangleStripAdjacency : public CPrimitiveMode 4561{ 4562public: 4563 virtual std::string Title() 4564 { 4565 return "glDrawArraysIndirect mode: GL_TRIANGLE_STRIP_ADJACENCY"; 4566 } 4567 4568 virtual std::string Purpose() 4569 { 4570 return "Verify that glDrawArraysIndirect with GL_TRIANGLE_STRIP_ADJACENCY works correctly"; 4571 } 4572 4573 virtual std::string Method() 4574 { 4575 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4576 "3. Draw primitives using glDrawArraysIndirect" NL "4. Verify results"; 4577 } 4578 4579 virtual std::string PassCriteria() 4580 { 4581 return "The test will pass if no OpenGL errors reported"; 4582 } 4583 4584 CModeDrawArraysTriangleStripAdjacency() : CPrimitiveMode(DRAW_ARRAYS, GL_TRIANGLE_STRIP_ADJACENCY, 4, 4) 4585 { 4586 } 4587 virtual long Run() 4588 { 4589 if (!IsGeometryShaderSupported<api>()) 4590 return NOT_SUPPORTED; 4591 return CPrimitiveMode::Run<api>(); 4592 } 4593}; 4594 4595template <typename api> 4596class CModeDrawElementsPoints : public CPrimitiveMode 4597{ 4598public: 4599 virtual std::string Title() 4600 { 4601 return "glDrawElementsIndirect mode: GL_POINTS"; 4602 } 4603 4604 virtual std::string Purpose() 4605 { 4606 return "Verify that glDrawElementsIndirect with GL_POINTS works correctly"; 4607 } 4608 4609 virtual std::string Method() 4610 { 4611 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4612 "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results"; 4613 } 4614 4615 virtual std::string PassCriteria() 4616 { 4617 return "The test will pass if no OpenGL errors reported"; 4618 } 4619 4620 CModeDrawElementsPoints() : CPrimitiveMode(DRAW_ELEMENTS, GL_POINTS) 4621 { 4622 } 4623 4624 virtual long Run() 4625 { 4626 return CPrimitiveMode::Run<api>(true); 4627 } 4628}; 4629 4630template <typename api> 4631class CModeDrawElementsLines : public CPrimitiveMode 4632{ 4633public: 4634 virtual std::string Title() 4635 { 4636 return "glDrawElementsIndirect mode: GL_LINES"; 4637 } 4638 4639 virtual std::string Purpose() 4640 { 4641 return "Verify that glDrawElementsIndirect with GL_LINES works correctly"; 4642 } 4643 4644 virtual std::string Method() 4645 { 4646 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4647 "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results"; 4648 } 4649 4650 virtual std::string PassCriteria() 4651 { 4652 return "The test will pass if no OpenGL errors reported"; 4653 } 4654 4655 CModeDrawElementsLines() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINES) 4656 { 4657 } 4658 virtual long Run() 4659 { 4660 return CPrimitiveMode::Run<api>(); 4661 } 4662}; 4663 4664template <typename api> 4665class CModeDrawElementsLineStrip : public CPrimitiveMode 4666{ 4667public: 4668 virtual std::string Title() 4669 { 4670 return "glDrawElementsIndirect mode: GL_LINE_STRIP"; 4671 } 4672 4673 virtual std::string Purpose() 4674 { 4675 return "Verify that glDrawElementsIndirect with GL_LINE_STRIP works correctly"; 4676 } 4677 4678 virtual std::string Method() 4679 { 4680 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4681 "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results"; 4682 } 4683 4684 virtual std::string PassCriteria() 4685 { 4686 return "The test will pass if no OpenGL errors reported"; 4687 } 4688 4689 CModeDrawElementsLineStrip() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINE_STRIP) 4690 { 4691 } 4692 virtual long Run() 4693 { 4694 return CPrimitiveMode::Run<api>(); 4695 } 4696}; 4697 4698template <typename api> 4699class CModeDrawElementsLineLoop : public CPrimitiveMode 4700{ 4701public: 4702 virtual std::string Title() 4703 { 4704 return "glDrawElementsIndirect mode: GL_LINE_LOOP"; 4705 } 4706 4707 virtual std::string Purpose() 4708 { 4709 return "Verify that glDrawElementsIndirect with GL_LINE_LOOP works correctly"; 4710 } 4711 4712 virtual std::string Method() 4713 { 4714 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4715 "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results"; 4716 } 4717 4718 virtual std::string PassCriteria() 4719 { 4720 return "The test will pass if no OpenGL errors reported"; 4721 } 4722 4723 CModeDrawElementsLineLoop() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINE_LOOP) 4724 { 4725 } 4726 virtual long Run() 4727 { 4728 return CPrimitiveMode::Run<api>(); 4729 } 4730}; 4731 4732template <typename api> 4733class CModeDrawElementsTriangleStrip : public CPrimitiveMode 4734{ 4735public: 4736 virtual std::string Title() 4737 { 4738 return "glDrawElementsIndirect mode: GL_TRIANGLE_STRIP"; 4739 } 4740 4741 virtual std::string Purpose() 4742 { 4743 return "Verify that glDrawElementsIndirect with GL_TRIANGLE_STRIP works correctly"; 4744 } 4745 4746 virtual std::string Method() 4747 { 4748 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4749 "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results"; 4750 } 4751 4752 virtual std::string PassCriteria() 4753 { 4754 return "The test will pass if no OpenGL errors reported"; 4755 } 4756 4757 CModeDrawElementsTriangleStrip() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLE_STRIP, 2, 2) 4758 { 4759 } 4760 virtual long Run() 4761 { 4762 return CPrimitiveMode::Run<api>(); 4763 } 4764}; 4765 4766template <typename api> 4767class CModeDrawElementsTriangleFan : public CPrimitiveMode 4768{ 4769public: 4770 virtual std::string Title() 4771 { 4772 return "glDrawElementsIndirect mode: GL_TRIANGLE_FAN"; 4773 } 4774 4775 virtual std::string Purpose() 4776 { 4777 return "Verify that glDrawElementsIndirect with GL_TRIANGLE_FAN works correctly"; 4778 } 4779 4780 virtual std::string Method() 4781 { 4782 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4783 "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results"; 4784 } 4785 4786 virtual std::string PassCriteria() 4787 { 4788 return "The test will pass if no OpenGL errors reported"; 4789 } 4790 4791 CModeDrawElementsTriangleFan() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLE_FAN, 2, 2) 4792 { 4793 } 4794 virtual long Run() 4795 { 4796 return CPrimitiveMode::Run<api>(); 4797 } 4798}; 4799 4800template <typename api> 4801class CModeDrawElementsLinesAdjacency : public CPrimitiveMode 4802{ 4803public: 4804 virtual std::string Title() 4805 { 4806 return "glDrawElementsIndirect mode: GL_LINES_ADJACENCY"; 4807 } 4808 4809 virtual std::string Purpose() 4810 { 4811 return "Verify that glDrawElementsIndirect with GL_LINES_ADJACENCY works correctly"; 4812 } 4813 4814 virtual std::string Method() 4815 { 4816 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4817 "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results"; 4818 } 4819 4820 virtual std::string PassCriteria() 4821 { 4822 return "The test will pass if no OpenGL errors reported"; 4823 } 4824 4825 CModeDrawElementsLinesAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINES_ADJACENCY) 4826 { 4827 } 4828 virtual long Run() 4829 { 4830 if (!IsGeometryShaderSupported<api>()) 4831 return NOT_SUPPORTED; 4832 return CPrimitiveMode::Run<api>(); 4833 } 4834}; 4835 4836template <typename api> 4837class CModeDrawElementsLineStripAdjacency : public CPrimitiveMode 4838{ 4839public: 4840 virtual std::string Title() 4841 { 4842 return "glDrawElementsIndirect mode: GL_LINE_STRIP_ADJACENCY"; 4843 } 4844 4845 virtual std::string Purpose() 4846 { 4847 return "Verify that glDrawElementsIndirect with GL_LINE_STRIP_ADJACENCY works correctly"; 4848 } 4849 4850 virtual std::string Method() 4851 { 4852 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4853 "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results"; 4854 } 4855 4856 virtual std::string PassCriteria() 4857 { 4858 return "The test will pass if no OpenGL errors reported"; 4859 } 4860 4861 CModeDrawElementsLineStripAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_LINE_STRIP_ADJACENCY) 4862 { 4863 } 4864 virtual long Run() 4865 { 4866 if (!IsGeometryShaderSupported<api>()) 4867 return NOT_SUPPORTED; 4868 return CPrimitiveMode::Run<api>(); 4869 } 4870}; 4871 4872template <typename api> 4873class CModeDrawElementsTrianglesAdjacency : public CPrimitiveMode 4874{ 4875public: 4876 virtual std::string Title() 4877 { 4878 return "glDrawElementsIndirect mode: GL_TRIANGLES_ADJACENCY"; 4879 } 4880 4881 virtual std::string Purpose() 4882 { 4883 return "Verify that glDrawElementsIndirect with GL_TRIANGLES_ADJACENCY works correctly"; 4884 } 4885 4886 virtual std::string Method() 4887 { 4888 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4889 "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results"; 4890 } 4891 4892 virtual std::string PassCriteria() 4893 { 4894 return "The test will pass if no OpenGL errors reported"; 4895 } 4896 4897 CModeDrawElementsTrianglesAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLES_ADJACENCY, 4, 4) 4898 { 4899 } 4900 virtual long Run() 4901 { 4902 if (!IsGeometryShaderSupported<api>()) 4903 return NOT_SUPPORTED; 4904 return CPrimitiveMode::Run<api>(); 4905 } 4906}; 4907 4908template <typename api> 4909class CModeDrawElementsTriangleStripAdjacency : public CPrimitiveMode 4910{ 4911public: 4912 virtual std::string Title() 4913 { 4914 return "glDrawElementsIndirect mode: GL_TRIANGLE_STRIP_ADJACENCY"; 4915 } 4916 4917 virtual std::string Purpose() 4918 { 4919 return "Verify that glDrawElementsIndirect with GL_TRIANGLE_STRIP_ADJACENCY works correctly"; 4920 } 4921 4922 virtual std::string Method() 4923 { 4924 return "1. Create and fill VBO" NL "2. Create indirect buffer" NL 4925 "3. Draw primitives using glDrawElementsIndirect" NL "4. Verify results"; 4926 } 4927 4928 virtual std::string PassCriteria() 4929 { 4930 return "The test will pass if no OpenGL errors reported"; 4931 } 4932 4933 CModeDrawElementsTriangleStripAdjacency() : CPrimitiveMode(DRAW_ELEMENTS, GL_TRIANGLE_STRIP_ADJACENCY, 4, 4) 4934 { 4935 } 4936 virtual long Run() 4937 { 4938 if (!IsGeometryShaderSupported<api>()) 4939 return NOT_SUPPORTED; 4940 return CPrimitiveMode::Run<api>(); 4941 } 4942}; 4943 4944class CTransformFeedback : public DrawIndirectBase 4945{ 4946public: 4947 virtual long Setup() 4948 { 4949 glClear(GL_COLOR_BUFFER_BIT); 4950 return NO_ERROR; 4951 } 4952 4953 template <typename api> 4954 long Run() 4955 { 4956 CColorArray coords; 4957 PrimitiveGen(GL_TRIANGLE_STRIP, 8, 8, coords); 4958 4959 glClear(GL_COLOR_BUFFER_BIT); 4960 4961 _program = CreateProgram(Vsh<api>(), "", shaders::fshSimple<api>(), false); 4962 const GLchar* varyings[] = { "dataOut" }; 4963 glTransformFeedbackVaryings(_program, 1, varyings, GL_INTERLEAVED_ATTRIBS); 4964 glLinkProgram(_program); 4965 if (!CheckProgram(_program)) 4966 { 4967 return ERROR; 4968 } 4969 glUseProgram(_program); 4970 4971 glGenBuffers(1, &_vbo); 4972 glBindBuffer(GL_ARRAY_BUFFER, _vbo); 4973 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STATIC_DRAW); 4974 4975 glGenBuffers(1, &_ubo); 4976 glBindBuffer(GL_UNIFORM_BUFFER, _ubo); 4977 glBufferData(GL_UNIFORM_BUFFER, 4 * 5 * sizeof(GLuint), NULL, GL_STATIC_DRAW); 4978 glBindBufferBase(GL_UNIFORM_BUFFER, glGetUniformBlockIndex(_program, "BLOCK"), _ubo); 4979 std::vector<GLuint> uboData; 4980 4981 switch (_drawFunc) 4982 { 4983 case DRAW_ARRAYS: 4984 { 4985 uboData.resize(4 * 4, 0); 4986 4987 uboData[0] = static_cast<GLuint>(coords.size()); //count 4988 uboData[4] = 1; //primcount 4989 uboData[8] = 0; //first 4990 uboData[12] = 0; //mbz 4991 } 4992 break; 4993 case DRAW_ELEMENTS: 4994 { 4995 uboData.resize(4 * 5, 0); 4996 uboData[0] = static_cast<GLuint>(coords.size()); //count 4997 uboData[4] = 1; //primcount 4998 uboData[8] = 0; //firstindex 4999 uboData[12] = 0; //basevertex 5000 uboData[16] = 0; //mbz 5001 } 5002 break; 5003 default: 5004 throw std::runtime_error("Unknown draw function!"); 5005 break; 5006 } 5007 glBufferSubData(GL_UNIFORM_BUFFER, 0, (GLsizeiptr)(uboData.size() * sizeof(uboData[0])), &uboData[0]); 5008 5009 glGenVertexArrays(1, &_vao); 5010 glBindVertexArray(_vao); 5011 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 5012 glEnableVertexAttribArray(0); 5013 5014 CElementArray elements(coords.size(), 0); 5015 for (size_t i = 0; i < elements.size(); ++i) 5016 { 5017 elements[i] = static_cast<GLuint>(i); 5018 } 5019 5020 glGenBuffers(1, &_ebo); 5021 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 5022 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 5023 GL_STATIC_DRAW); 5024 5025 glGenBuffers(1, &_bufferIndirect); 5026 5027 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, _bufferIndirect); 5028 GLuint zeroes[] = { 0, 0, 0, 0, 0 }; 5029 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(zeroes), zeroes, GL_DYNAMIC_DRAW); 5030 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _bufferIndirect); 5031 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 5032 5033 glEnable(GL_RASTERIZER_DISCARD); 5034 glBeginTransformFeedback(GL_POINTS); 5035 glDrawArrays(GL_POINTS, 0, 5); 5036 glEndTransformFeedback(); 5037 glDisable(GL_RASTERIZER_DISCARD); 5038 5039 switch (_drawFunc) 5040 { 5041 case DRAW_ARRAYS: 5042 glDrawArraysIndirect(GL_TRIANGLES, 0); 5043 break; 5044 case DRAW_ELEMENTS: 5045 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0); 5046 5047 break; 5048 default: 5049 throw std::runtime_error("Unknown draw function!"); 5050 break; 5051 } 5052 5053 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f)); 5054 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 5055 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 5056 5057 DIResult result; 5058 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 5059 getWindowHeight())); 5060 5061 return result.code(); 5062 } 5063 5064 virtual long Cleanup() 5065 { 5066 glDisableVertexAttribArray(0); 5067 glBindBuffer(GL_ARRAY_BUFFER, 0); 5068 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 5069 glBindVertexArray(0); 5070 glUseProgram(0); 5071 5072 if (_vao) 5073 { 5074 glDeleteVertexArrays(1, &_vao); 5075 } 5076 if (_vbo) 5077 { 5078 glDeleteBuffers(1, &_vbo); 5079 } 5080 if (_ebo) 5081 { 5082 glDeleteBuffers(1, &_ebo); 5083 } 5084 if (_ubo) 5085 { 5086 glDeleteBuffers(1, &_ubo); 5087 } 5088 if (_bufferIndirect) 5089 { 5090 glDeleteBuffers(1, &_bufferIndirect); 5091 } 5092 if (_program) 5093 { 5094 glDeleteProgram(_program); 5095 } 5096 return NO_ERROR; 5097 } 5098 5099 CTransformFeedback(TDrawFunction drawFunc) 5100 : _drawFunc(drawFunc), _program(0), _vao(0), _vbo(0), _ebo(0), _ubo(0), _bufferIndirect(0) 5101 { 5102 } 5103 5104private: 5105 TDrawFunction _drawFunc; 5106 GLuint _program; 5107 GLuint _vao, _vbo, _ebo, _ubo, _bufferIndirect; 5108 5109 CTransformFeedback(); 5110 5111 template <typename api> 5112 std::string Vsh() 5113 { 5114 return api::glslVer() + NL "flat out highp uint dataOut;" NL "in vec4 i_vertex;" NL 5115 "layout(std140) uniform BLOCK {" NL " uint m[5];" NL "} b;" NL "void main() {" NL 5116 " dataOut = b.m[min(4, gl_VertexID)];" NL " gl_Position = i_vertex;" NL "}"; 5117 } 5118}; 5119 5120template <typename api> 5121struct CTransformFeedbackArray : public CTransformFeedback 5122{ 5123 virtual std::string Title() 5124 { 5125 return "Transform feedback: glDrawArrayIndirect"; 5126 } 5127 5128 virtual std::string Purpose() 5129 { 5130 return "Verify that transform feedback works correctly with glDrawArrayIndirect"; 5131 } 5132 5133 virtual std::string Method() 5134 { 5135 return "1. Create data" NL "2. Use data as input to glDrawArrayIndirect" NL "3. Verify results"; 5136 } 5137 5138 virtual std::string PassCriteria() 5139 { 5140 return "The test will pass if no OpenGL errors reported"; 5141 } 5142 5143 CTransformFeedbackArray() : CTransformFeedback(DRAW_ARRAYS) 5144 { 5145 } 5146 5147 virtual long Run() 5148 { 5149 return CTransformFeedback::Run<api>(); 5150 } 5151}; 5152 5153template <typename api> 5154struct CTransformFeedbackElements : public CTransformFeedback 5155{ 5156 virtual std::string Title() 5157 { 5158 return "Transform feedback: glDrawElementsIndirect"; 5159 } 5160 5161 virtual std::string Purpose() 5162 { 5163 return "Verify that transform feedback works correctly with glDrawElementsIndirect"; 5164 } 5165 5166 virtual std::string Method() 5167 { 5168 return "1. Create data" NL "2. Use data as input to glDrawElementsIndirect" NL "3. Verify results"; 5169 } 5170 5171 virtual std::string PassCriteria() 5172 { 5173 return "The test will pass if no OpenGL errors reported"; 5174 } 5175 5176 CTransformFeedbackElements() : CTransformFeedback(DRAW_ELEMENTS) 5177 { 5178 } 5179 5180 virtual long Run() 5181 { 5182 return CTransformFeedback::Run<api>(); 5183 } 5184}; 5185 5186class CComputeBase : public DrawIndirectBase 5187{ 5188public: 5189 virtual long Setup() 5190 { 5191 glClear(GL_COLOR_BUFFER_BIT); 5192 return NO_ERROR; 5193 } 5194 5195 template <typename api> 5196 long Run() 5197 { 5198 5199 int width, height; 5200 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 0, &width); 5201 glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 1, &height); 5202 5203 width = std::min(width, getWindowWidth()); 5204 height = std::min(height, getWindowHeight()); 5205 5206 glViewport(0, 0, width, height); 5207 5208 CColorArray coords(width * height, tcu::Vec4(0)); 5209 CColorArray colors(width * height, tcu::Vec4(0)); 5210 5211 _program = CreateProgram(Vsh<api>(), "", Fsh<api>(), false); 5212 glBindAttribLocation(_program, 0, "in_coords"); 5213 glBindAttribLocation(_program, 1, "in_colors"); 5214 glLinkProgram(_program); 5215 if (!CheckProgram(_program)) 5216 { 5217 return ERROR; 5218 } 5219 glUseProgram(_program); 5220 5221 glGenVertexArrays(1, &_vao); 5222 glBindVertexArray(_vao); 5223 5224 glGenBuffers(1, &_bufferCoords); 5225 glBindBuffer(GL_ARRAY_BUFFER, _bufferCoords); 5226 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), 0, GL_STREAM_DRAW); 5227 5228 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0); 5229 glEnableVertexAttribArray(0); 5230 5231 glGenBuffers(1, &_bufferColors); 5232 glBindBuffer(GL_ARRAY_BUFFER, _bufferColors); 5233 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(colors.size() * sizeof(colors[0])), 0, GL_STREAM_DRAW); 5234 5235 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(tcu::Vec4), 0); 5236 glEnableVertexAttribArray(1); 5237 5238 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 5239 DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 }; 5240 5241 CElementArray elements(width * height, 0); 5242 for (size_t i = 0; i < elements.size(); ++i) 5243 { 5244 elements[i] = static_cast<GLuint>(i); 5245 } 5246 5247 glGenBuffers(1, &_bufferIndirect); 5248 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 5249 switch (_drawFunc) 5250 { 5251 case DRAW_ARRAYS: 5252 { 5253 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW); 5254 } 5255 break; 5256 case DRAW_ELEMENTS: 5257 { 5258 glGenBuffers(1, &_ebo); 5259 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 5260 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 5261 GL_STATIC_DRAW); 5262 5263 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, 5264 GL_STATIC_DRAW); 5265 } 5266 break; 5267 default: 5268 throw std::runtime_error("Unknown draw function!"); 5269 break; 5270 } 5271 5272 _programCompute = CreateComputeProgram(Csh<api>(), false); 5273 glLinkProgram(_programCompute); 5274 if (!CheckProgram(_programCompute)) 5275 { 5276 return ERROR; 5277 } 5278 glUseProgram(_programCompute); 5279 glUniform1ui(glGetUniformLocation(_programCompute, "width"), width); 5280 glUniform1ui(glGetUniformLocation(_programCompute, "height"), height); 5281 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, _bufferCoords); 5282 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, _bufferColors); 5283 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, _bufferIndirect); 5284 5285 glDispatchCompute(width, height, 1); 5286 glMemoryBarrier(GL_COMMAND_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT); 5287 5288 glUseProgram(_program); 5289 5290 switch (_drawFunc) 5291 { 5292 case DRAW_ARRAYS: 5293 { 5294 glDrawArraysIndirect(GL_POINTS, 0); 5295 } 5296 break; 5297 case DRAW_ELEMENTS: 5298 { 5299 glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, 0); 5300 } 5301 break; 5302 default: 5303 throw std::runtime_error("Unknown draw function!"); 5304 break; 5305 } 5306 5307 CColorArray bufferRef1(width * height / 4, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 5308 CColorArray bufferRef2(width * height / 4, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f)); 5309 CColorArray bufferRef3(width * height / 4, tcu::Vec4(0.0f, 0.5f, 0.0f, 1.0f)); 5310 CColorArray bufferRef4(width * height / 4, tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f)); 5311 CColorArray bufferTest(width * height / 4, tcu::Vec4(0.0f)); 5312 5313 DIResult result; 5314 ReadPixelsFloat<api>(0, 0, width / 2, height / 2, &bufferTest[0]); 5315 result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef1, width / 2, height / 2)) 5316 << "Region 0 verification failed"; 5317 5318 ReadPixelsFloat<api>((width + 1) / 2, 0, width / 2, height / 2, &bufferTest[0]); 5319 result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef2, width / 2, height / 2)) 5320 << "Region 1 verification failed"; 5321 5322 ReadPixelsFloat<api>(0, (height + 1) / 2, width / 2, height / 2, &bufferTest[0]); 5323 result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef3, width / 2, height / 2)) 5324 << "Region 2 verification failed"; 5325 5326 ReadPixelsFloat<api>((width + 1) / 2, (height + 1) / 2, width / 2, height / 2, &bufferTest[0]); 5327 result.sub_result(BuffersCompare(bufferTest, width / 2, height / 2, bufferRef4, width / 2, height / 2)) 5328 << "Region 3 verification failed"; 5329 5330 return result.code(); 5331 } 5332 5333 virtual long Cleanup() 5334 { 5335 glDisableVertexAttribArray(1); 5336 glDisableVertexAttribArray(0); 5337 glDeleteProgram(_program); 5338 glDeleteProgram(_programCompute); 5339 glDeleteVertexArrays(1, &_vao); 5340 if (_ebo) 5341 glDeleteBuffers(1, &_ebo); 5342 glDeleteBuffers(1, &_bufferCoords); 5343 glDeleteBuffers(1, &_bufferColors); 5344 glDeleteBuffers(1, &_bufferIndirect); 5345 glViewport(0, 0, getWindowWidth(), getWindowHeight()); 5346 return NO_ERROR; 5347 } 5348 CComputeBase(TDrawFunction drawFunc) 5349 : _drawFunc(drawFunc) 5350 , _program(0) 5351 , _programCompute(0) 5352 , _vao(0) 5353 , _ebo(0) 5354 , _bufferCoords(0) 5355 , _bufferColors(0) 5356 , _bufferIndirect(0) 5357 { 5358 } 5359 5360private: 5361 CComputeBase(); 5362 TDrawFunction _drawFunc; 5363 5364 template <typename api> 5365 std::string Vsh() 5366 { 5367 return api::glslVer() + NL "in vec4 in_coords;" NL "in vec4 in_colors;" NL "out vec4 colors;" NL 5368 "void main() {" NL " colors = in_colors;" NL " gl_Position = in_coords;" NL 5369 "#if defined(GL_ES)" NL " gl_PointSize = 1.0;" NL "#endif" NL "}"; 5370 } 5371 5372 template <typename api> 5373 std::string Fsh() 5374 { 5375 return api::glslVer() + NL "precision highp float;" NL "in vec4 colors;" NL "out vec4 outColor;" NL 5376 "void main() {" NL " outColor = colors;" NL "}"; 5377 } 5378 5379 template <typename api> 5380 std::string Csh() 5381 { 5382 return api::glslVer(true) + NL "precision highp int; " NL 5383 "precision highp float; " NL 5384 " " NL 5385 "layout(local_size_x = 1) in; " NL 5386 "layout(std430, binding = 0) buffer Vertices { " NL 5387 " vec4 vertices[]; " NL 5388 "}; " NL 5389 "layout(std430, binding = 1) buffer Colors { " NL 5390 " vec4 colors[]; " NL 5391 "}; " NL 5392 "layout(std430, binding = 2) buffer Indirect { " NL 5393 " uint indirect[4]; " NL 5394 "}; " NL 5395 " " NL 5396 "uniform uint height; " NL 5397 "uniform uint width; " NL 5398 " " NL 5399 "void main() { " NL 5400 " uint w = gl_GlobalInvocationID.x; " NL 5401 " uint h = gl_GlobalInvocationID.y; " NL 5402 " float stepX = 2.0 / float(width); " NL 5403 " float stepY = 2.0 / float(height); " NL 5404 " float offsetX = -1.0 + stepX * float(w) + stepX / 2.0; " NL 5405 " float offsetY = -1.0 + stepY * float(h) + stepY / 2.0; " NL 5406 " uint arrayOffset = h * width + w; " NL 5407 " vertices[ arrayOffset ] = vec4(offsetX, offsetY, 0.0, 1.0);" NL 5408 " vec4 color = vec4(0.0, 0.0, 0.0, 1.0); " NL 5409 " if(w > (width / 2u - 1u)) { " NL 5410 " color = color + vec4(0.5, 0.0, 0.0, 0.0); " NL 5411 " } " NL 5412 " if(h > (height / 2u - 1u)) { " NL 5413 " color = color + vec4(0.0, 0.5, 0.0, 0.0); " NL 5414 " } " NL 5415 " colors[ arrayOffset ] = color; " NL 5416 " if(w == 0u && h == 0u) { " NL 5417 " indirect[0] = width * height; " NL 5418 " indirect[1] = 1u; " NL 5419 " } " NL 5420 "} "; 5421 } 5422 5423 GLuint _program, _programCompute; 5424 GLuint _vao; 5425 GLuint _ebo; 5426 GLuint _bufferCoords; 5427 GLuint _bufferColors; 5428 GLuint _bufferIndirect; 5429}; 5430 5431template <typename api> 5432struct CComputeShaderArray : public CComputeBase 5433{ 5434 virtual std::string Title() 5435 { 5436 return "Compute Shader: glDrawArrayIndirect"; 5437 } 5438 5439 virtual std::string Purpose() 5440 { 5441 return "Verify that data created by Compute Shader can be used as an input to glDrawArrayIndirect"; 5442 } 5443 5444 virtual std::string Method() 5445 { 5446 return "1. Create data by Compute Shader" NL "2. Use data as input to glDrawArrayIndirect" NL 5447 "3. Verify results"; 5448 } 5449 5450 virtual std::string PassCriteria() 5451 { 5452 return "The test will pass if no OpenGL errors reported"; 5453 } 5454 5455 CComputeShaderArray() : CComputeBase(DRAW_ARRAYS) 5456 { 5457 } 5458 5459 virtual long Run() 5460 { 5461 return CComputeBase::Run<api>(); 5462 } 5463}; 5464 5465template <typename api> 5466struct CComputeShaderElements : public CComputeBase 5467{ 5468 virtual std::string Title() 5469 { 5470 return "Compute Shader: glDrawElementsIndirect"; 5471 } 5472 5473 virtual std::string Purpose() 5474 { 5475 return "Verify that data created by Compute Shader can be used as an input to glDrawElementsIndirect"; 5476 } 5477 5478 virtual std::string Method() 5479 { 5480 return "1. Create data by Compute Shader" NL "2. Use data as input to glDrawElementsIndirect" NL 5481 "3. Verify results"; 5482 } 5483 5484 virtual std::string PassCriteria() 5485 { 5486 return "The test will pass if no OpenGL errors reported"; 5487 } 5488 5489 CComputeShaderElements() : CComputeBase(DRAW_ELEMENTS) 5490 { 5491 } 5492 5493 virtual long Run() 5494 { 5495 return CComputeBase::Run<api>(); 5496 } 5497}; 5498 5499template <typename api> 5500class CPrimitiveRestartElements : public DrawIndirectBase 5501{ 5502public: 5503 virtual std::string Title() 5504 { 5505 return "Primitive restart - glDrawElementsIndirect"; 5506 } 5507 5508 virtual std::string Purpose() 5509 { 5510 return "Verify that primitive restart works correctly with glDrawElementsIndirect"; 5511 } 5512 5513 virtual std::string Method() 5514 { 5515 return "1. Define primitives using VBO" NL "2. Draw primitives using glDrawElementsIndirect" NL 5516 "3. Verify results"; 5517 } 5518 5519 virtual std::string PassCriteria() 5520 { 5521 return "The test will pass if no OpenGL errors reported"; 5522 } 5523 5524 virtual long Setup() 5525 { 5526 glClear(GL_COLOR_BUFFER_BIT); 5527 return NO_ERROR; 5528 } 5529 5530 int PrimitiveRestartIndex(); 5531 5532 void EnablePrimitiveRestart(); 5533 5534 void DisablePrimitiveRestart(); 5535 5536 virtual long Run() 5537 { 5538 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 5539 if (!_program) 5540 { 5541 return ERROR; 5542 } 5543 glUseProgram(_program); 5544 5545 CColorArray coords1; 5546 TriangleStipGen(coords1, -1.0f, 1.0f, -1.0, -0.5, 2); 5547 5548 CColorArray coords2; 5549 TriangleStipGen(coords2, -1.0f, 1.0f, 0.5, 1.0, 4); 5550 5551 glGenVertexArrays(1, &_vao); 5552 glBindVertexArray(_vao); 5553 5554 glGenBuffers(1, &_buffer); 5555 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 5556 5557 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords1.size() + coords2.size()) * sizeof(coords1[0]), NULL, 5558 GL_STREAM_DRAW); 5559 glBufferSubData(GL_ARRAY_BUFFER, 0, (GLsizeiptr)(coords1.size() * sizeof(coords1[0])), &coords1[0]); 5560 glBufferSubData(GL_ARRAY_BUFFER, (GLintptr)(coords1.size() * sizeof(coords1[0])), 5561 (GLsizeiptr)(coords2.size() * sizeof(coords2[0])), &coords2[0]); 5562 glVertexAttribPointer(0, sizeof(coords1[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords1[0]), 0); 5563 glEnableVertexAttribArray(0); 5564 5565 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 5566 indirectElements.count = static_cast<GLuint>(coords1.size() + coords2.size() + 1); 5567 indirectElements.primCount = static_cast<GLuint>((coords1.size() + coords2.size()) / 2); 5568 5569 CElementArray elements; 5570 for (size_t i = 0; i < coords1.size(); ++i) 5571 { 5572 elements.push_back(static_cast<GLuint>(i)); 5573 } 5574 5575 elements.push_back(PrimitiveRestartIndex()); 5576 for (size_t i = 0; i < coords2.size(); ++i) 5577 { 5578 elements.push_back(static_cast<GLuint>(coords1.size() + i)); 5579 } 5580 5581 glGenBuffers(1, &_bufferIndirect); 5582 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 5583 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW); 5584 5585 glGenBuffers(1, &_ebo); 5586 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 5587 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 5588 GL_STATIC_DRAW); 5589 5590 EnablePrimitiveRestart(); 5591 5592 glDrawElementsIndirect(GL_TRIANGLE_STRIP, GL_UNSIGNED_INT, 0); 5593 5594 CColorArray bufferRef1(getWindowWidth() * getWindowHeight() / 4, tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f)); 5595 CColorArray bufferRef2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f)); 5596 CColorArray bufferTest1(getWindowWidth() * getWindowHeight() / 4, tcu::Vec4(0.0f)); 5597 CColorArray bufferTest2(getWindowWidth() * getWindowHeight() / 2, tcu::Vec4(0.0f)); 5598 5599 DIResult result; 5600 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight() / 4, &bufferTest1[0]); 5601 result.sub_result(BuffersCompare(bufferTest1, getWindowWidth(), getWindowHeight() / 4, bufferRef1, 5602 getWindowWidth(), getWindowHeight() / 4)); 5603 5604 ReadPixelsFloat<api>(0, (getWindowHeight() + 3) / 4, getWindowWidth(), getWindowHeight() / 2, &bufferTest2[0]); 5605 result.sub_result(BuffersCompare(bufferTest2, getWindowWidth(), getWindowHeight() / 2, bufferRef2, 5606 getWindowWidth(), getWindowHeight() / 2)); 5607 5608 ReadPixelsFloat<api>(0, (getWindowHeight() * 3 + 3) / 4, getWindowWidth(), getWindowHeight() / 4, 5609 &bufferTest1[0]); 5610 result.sub_result(BuffersCompare(bufferTest1, getWindowWidth(), getWindowHeight() / 4, bufferRef1, 5611 getWindowWidth(), getWindowHeight() / 4)); 5612 5613 return result.code(); 5614 } 5615 5616 virtual long Cleanup() 5617 { 5618 5619 DisablePrimitiveRestart(); 5620 glDisableVertexAttribArray(0); 5621 glUseProgram(0); 5622 glDeleteProgram(_program); 5623 glDeleteVertexArrays(1, &_vao); 5624 glDeleteBuffers(1, &_buffer); 5625 glDeleteBuffers(1, &_ebo); 5626 glDeleteBuffers(1, &_bufferIndirect); 5627 return NO_ERROR; 5628 } 5629 5630private: 5631 void TriangleStipGen(CColorArray& coords, float widthStart, float widthEnd, float heightStart, float heightEnd, 5632 unsigned int primNum) 5633 { 5634 float widthStep = (widthEnd - widthStart) / static_cast<float>(primNum); 5635 float heightStep = (heightEnd - heightStart) / static_cast<float>(primNum); 5636 for (unsigned int i = 0; i < primNum; ++i) 5637 { 5638 float heightOffset = heightStart + heightStep * static_cast<float>(i); 5639 for (unsigned int j = 0; j < primNum; ++j) 5640 { 5641 float widthOffset = widthStart + widthStep * static_cast<float>(j); 5642 5643 coords.push_back(tcu::Vec4(widthOffset, heightOffset, 0.0f, 1.0f)); 5644 coords.push_back(tcu::Vec4(widthOffset, heightOffset + heightStep, 0.0f, 1.0f)); 5645 coords.push_back(tcu::Vec4(widthOffset + widthStep, heightOffset, 0.0f, 1.0f)); 5646 coords.push_back(tcu::Vec4(widthOffset + widthStep, heightOffset + heightStep, 0.0f, 1.0f)); 5647 } 5648 } 5649 } 5650 GLuint _program; 5651 GLuint _vao, _buffer, _ebo, _bufferIndirect; 5652}; 5653 5654template <> 5655int CPrimitiveRestartElements<test_api::ES3>::PrimitiveRestartIndex() 5656{ 5657 return 0xffffffff; 5658} 5659 5660template <> 5661int CPrimitiveRestartElements<test_api::GL>::PrimitiveRestartIndex() 5662{ 5663 return 3432432; 5664} 5665 5666template <> 5667void CPrimitiveRestartElements<test_api::ES3>::DisablePrimitiveRestart() 5668{ 5669 glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX); 5670} 5671 5672template <> 5673void CPrimitiveRestartElements<test_api::GL>::DisablePrimitiveRestart() 5674{ 5675 glDisable(GL_PRIMITIVE_RESTART); 5676} 5677 5678template <> 5679void CPrimitiveRestartElements<test_api::ES3>::EnablePrimitiveRestart() 5680{ 5681 glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX); 5682} 5683 5684template <> 5685void CPrimitiveRestartElements<test_api::GL>::EnablePrimitiveRestart() 5686{ 5687 glPrimitiveRestartIndex(PrimitiveRestartIndex()); 5688 glEnable(GL_PRIMITIVE_RESTART); 5689} 5690 5691template <typename api> 5692class CNonZeroReservedMustBeZeroArray : public DrawIndirectBase 5693{ 5694 virtual std::string Title() 5695 { 5696 return "non-zero reservedMustBeZero - glDrawArrayIndirect"; 5697 } 5698 5699 virtual std::string Purpose() 5700 { 5701 return "Verify that no driver crash occurred"; 5702 } 5703 5704 virtual std::string Method() 5705 { 5706 return "Call glDrawArrayIndirect with non-zero ReservedMustBeZero"; 5707 } 5708 5709 virtual std::string PassCriteria() 5710 { 5711 return "The test will pass if no OpenGL errors reported and no driver crash occurred"; 5712 } 5713 5714 virtual long Setup() 5715 { 5716 glClear(GL_COLOR_BUFFER_BIT); 5717 return NO_ERROR; 5718 } 5719 5720 virtual long Run() 5721 { 5722 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 5723 if (!_program) 5724 { 5725 return ERROR; 5726 } 5727 glUseProgram(_program); 5728 5729 CColorArray coords; 5730 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 5731 5732 glGenVertexArrays(1, &_vao); 5733 glBindVertexArray(_vao); 5734 5735 glGenBuffers(1, &_buffer); 5736 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 5737 5738 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 5739 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 5740 glEnableVertexAttribArray(0); 5741 5742 DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 }; 5743 indirectArrays.count = static_cast<GLuint>(coords.size()); 5744 indirectArrays.primCount = 1; 5745 indirectArrays.first = 0; 5746 indirectArrays.reservedMustBeZero = 2312; 5747 5748 glGenBuffers(1, &_bufferIndirect); 5749 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 5750 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW); 5751 5752 glDrawArraysIndirect(GL_TRIANGLES, 0); 5753 5754 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f)); 5755 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 5756 5757 DIResult result; 5758 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 5759 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 5760 getWindowHeight())); 5761 5762 return result.code(); 5763 } 5764 5765 virtual long Cleanup() 5766 { 5767 glDisableVertexAttribArray(0); 5768 glUseProgram(0); 5769 glDeleteProgram(_program); 5770 glDeleteVertexArrays(1, &_vao); 5771 glDeleteBuffers(1, &_buffer); 5772 glDeleteBuffers(1, &_bufferIndirect); 5773 return NO_ERROR; 5774 } 5775 5776private: 5777 GLuint _program; 5778 GLuint _vao, _buffer, _bufferIndirect; 5779}; 5780 5781template <typename api> 5782struct CNonZeroReservedMustBeZeroElements : public DrawIndirectBase 5783{ 5784 virtual std::string Title() 5785 { 5786 return "non-zero reservedMustBeZero - glDrawElementsIndirect"; 5787 } 5788 5789 virtual std::string Purpose() 5790 { 5791 return "Verify that no driver crash occurred"; 5792 } 5793 5794 virtual std::string Method() 5795 { 5796 return "Call glDrawElementsIndirect with non-zero ReservedMustBeZero"; 5797 } 5798 5799 virtual std::string PassCriteria() 5800 { 5801 return "The test will pass if no OpenGL errors reported and no driver crash occurred"; 5802 } 5803 5804 virtual long Setup() 5805 { 5806 glClear(GL_COLOR_BUFFER_BIT); 5807 return NO_ERROR; 5808 } 5809 5810 virtual long Run() 5811 { 5812 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 5813 if (!_program) 5814 { 5815 return ERROR; 5816 } 5817 glUseProgram(_program); 5818 5819 CColorArray coords; 5820 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 5821 5822 glGenVertexArrays(1, &_vao); 5823 glBindVertexArray(_vao); 5824 5825 glGenBuffers(1, &_buffer); 5826 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 5827 5828 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 5829 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 5830 glEnableVertexAttribArray(0); 5831 5832 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 5833 indirectElements.count = static_cast<GLuint>(coords.size()); 5834 indirectElements.primCount = 1; 5835 indirectElements.baseVertex = 0; 5836 indirectElements.firstIndex = 0; 5837 indirectElements.reservedMustBeZero = 1; 5838 5839 CElementArray elements(coords.size(), 0); 5840 for (size_t i = 0; i < elements.size(); ++i) 5841 { 5842 elements[i] = static_cast<GLuint>(i); 5843 } 5844 5845 glGenBuffers(1, &_bufferIndirect); 5846 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 5847 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW); 5848 5849 glGenBuffers(1, &_ebo); 5850 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 5851 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 5852 GL_STATIC_DRAW); 5853 5854 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0); 5855 5856 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.1f, 0.2f, 0.3f, 1.0f)); 5857 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 5858 5859 DIResult result; 5860 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 5861 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 5862 getWindowHeight())); 5863 5864 return result.code(); 5865 } 5866 5867 virtual long Cleanup() 5868 { 5869 glDisableVertexAttribArray(0); 5870 glUseProgram(0); 5871 glDeleteProgram(_program); 5872 glDeleteVertexArrays(1, &_vao); 5873 glDeleteBuffers(1, &_buffer); 5874 glDeleteBuffers(1, &_ebo); 5875 glDeleteBuffers(1, &_bufferIndirect); 5876 return NO_ERROR; 5877 } 5878 5879private: 5880 GLuint _program; 5881 GLuint _vao, _buffer, _ebo, _bufferIndirect; 5882}; 5883 5884template <typename api> 5885struct CNegativeZeroBufferArray : public DrawIndirectBase 5886{ 5887 virtual std::string Title() 5888 { 5889 return "Negative: no indirect buffer/parameter - glDrawArrayIndirect"; 5890 } 5891 5892 virtual std::string Purpose() 5893 { 5894 return "Verify that a driver sets error and no driver crash occurred"; 5895 } 5896 5897 virtual std::string Method() 5898 { 5899 return "Call glDrawArrayIndirect"; 5900 } 5901 5902 virtual std::string PassCriteria() 5903 { 5904 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 5905 } 5906 5907 virtual long Setup() 5908 { 5909 glClear(GL_COLOR_BUFFER_BIT); 5910 return NO_ERROR; 5911 } 5912 5913 virtual long Run() 5914 { 5915 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 5916 if (!_program) 5917 { 5918 return ERROR; 5919 } 5920 glUseProgram(_program); 5921 5922 CColorArray coords; 5923 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 5924 5925 glGenVertexArrays(1, &_vao); 5926 glBindVertexArray(_vao); 5927 5928 glGenBuffers(1, &_buffer); 5929 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 5930 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 5931 5932 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 5933 glEnableVertexAttribArray(0); 5934 5935 glDrawArraysIndirect(GL_TRIANGLES, 0); 5936 DIResult result; 5937 if (glGetError() != GL_INVALID_OPERATION) 5938 { 5939 result.error() << "Invalid error code returned by a driver"; 5940 } 5941 5942 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 5943 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f)); 5944 5945 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 5946 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 5947 getWindowHeight())); 5948 5949 return result.code(); 5950 } 5951 5952 virtual long Cleanup() 5953 { 5954 glDisableVertexAttribArray(0); 5955 glUseProgram(0); 5956 glDeleteProgram(_program); 5957 glDeleteVertexArrays(1, &_vao); 5958 glDeleteBuffers(1, &_buffer); 5959 return NO_ERROR; 5960 } 5961 5962private: 5963 GLuint _program; 5964 GLuint _vao, _buffer; 5965}; 5966 5967template <typename api> 5968struct CNegativeZeroBufferElements : public DrawIndirectBase 5969{ 5970 virtual std::string Title() 5971 { 5972 return "Negative: no indirect buffer/parameter - glDrawElementsIndirect"; 5973 } 5974 5975 virtual std::string Purpose() 5976 { 5977 return "Verify that a driver sets error and no driver crash occurred"; 5978 } 5979 5980 virtual std::string Method() 5981 { 5982 return "Call glDrawElementsIndirect"; 5983 } 5984 5985 virtual std::string PassCriteria() 5986 { 5987 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 5988 } 5989 5990 virtual long Setup() 5991 { 5992 glClear(GL_COLOR_BUFFER_BIT); 5993 return NO_ERROR; 5994 } 5995 5996 virtual long Run() 5997 { 5998 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 5999 if (!_program) 6000 { 6001 return ERROR; 6002 } 6003 glUseProgram(_program); 6004 6005 CColorArray coords; 6006 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 6007 6008 glGenVertexArrays(1, &_vao); 6009 glBindVertexArray(_vao); 6010 6011 glGenBuffers(1, &_buffer); 6012 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 6013 6014 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 6015 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 6016 glEnableVertexAttribArray(0); 6017 6018 CElementArray elements(coords.size(), 0); 6019 for (size_t i = 0; i < elements.size(); ++i) 6020 { 6021 elements[i] = static_cast<GLuint>(i); 6022 } 6023 6024 glGenBuffers(1, &_ebo); 6025 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 6026 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 6027 GL_STATIC_DRAW); 6028 6029 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0); 6030 6031 DIResult result; 6032 if (glGetError() != GL_INVALID_OPERATION) 6033 { 6034 result.error() << "Invalid error code returned by a driver"; 6035 } 6036 6037 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 6038 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f)); 6039 6040 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 6041 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 6042 getWindowHeight())); 6043 6044 return result.code(); 6045 } 6046 6047 virtual long Cleanup() 6048 { 6049 glDisableVertexAttribArray(0); 6050 glUseProgram(0); 6051 glDeleteProgram(_program); 6052 glDeleteVertexArrays(1, &_vao); 6053 glDeleteBuffers(1, &_buffer); 6054 glDeleteBuffers(1, &_ebo); 6055 return NO_ERROR; 6056 } 6057 6058private: 6059 GLuint _program; 6060 GLuint _vao, _buffer, _ebo; 6061}; 6062 6063template <typename api> 6064struct CNegativeInvalidModeArray : public DrawIndirectBase 6065{ 6066 virtual std::string Title() 6067 { 6068 return "Negative: invalid mode - glDrawArrayIndirect"; 6069 } 6070 6071 virtual std::string Purpose() 6072 { 6073 return "Verify that a driver sets error and no driver crash occurred"; 6074 } 6075 6076 virtual std::string Method() 6077 { 6078 return "Set invalid mode to glDrawArrayIndirect"; 6079 } 6080 6081 virtual std::string PassCriteria() 6082 { 6083 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 6084 } 6085 6086 virtual long Setup() 6087 { 6088 glClear(GL_COLOR_BUFFER_BIT); 6089 return NO_ERROR; 6090 } 6091 6092 virtual long Run() 6093 { 6094 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 6095 if (!_program) 6096 { 6097 return ERROR; 6098 } 6099 glUseProgram(_program); 6100 6101 CColorArray coords; 6102 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 6103 6104 glGenVertexArrays(1, &_vao); 6105 glBindVertexArray(_vao); 6106 6107 glGenBuffers(1, &_buffer); 6108 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 6109 6110 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 6111 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 6112 glEnableVertexAttribArray(0); 6113 6114 DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 }; 6115 indirectArrays.count = static_cast<GLuint>(coords.size()); 6116 indirectArrays.primCount = 1; 6117 6118 glGenBuffers(1, &_bufferIndirect); 6119 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 6120 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW); 6121 6122 glDrawArraysIndirect(GL_FLOAT, 0); 6123 6124 DIResult result; 6125 if (glGetError() != GL_INVALID_ENUM) 6126 { 6127 result.error() << "Invalid error code returned by a driver for GL_FLOAT as mode"; 6128 } 6129 6130 glDrawArraysIndirect(GL_STATIC_DRAW, 0); 6131 if (glGetError() != GL_INVALID_ENUM) 6132 { 6133 result.error() << "Invalid error code returned by a driver for GL_STATIC_DRAW as mode"; 6134 } 6135 6136 glDrawArraysIndirect(GL_DRAW_INDIRECT_BUFFER, 0); 6137 if (glGetError() != GL_INVALID_ENUM) 6138 { 6139 result.error() << "Invalid error code returned by a driver for GL_DRAW_INDIRECT_BUFFER as mode"; 6140 } 6141 6142 glDrawArraysIndirect(GL_INVALID_ENUM, 0); 6143 if (glGetError() != GL_INVALID_ENUM) 6144 { 6145 result.error() << "Invalid error code returned by a driver for GL_INVALID_ENUM as mode"; 6146 } 6147 6148 glDrawArraysIndirect(GL_COLOR_BUFFER_BIT, 0); 6149 if (glGetError() != GL_INVALID_ENUM) 6150 { 6151 result.error() << "Invalid error code returned by a driver for GL_COLOR_BUFFER_BIT as mode"; 6152 } 6153 6154 glDrawArraysIndirect(GL_ARRAY_BUFFER, 0); 6155 if (glGetError() != GL_INVALID_ENUM) 6156 { 6157 result.error() << "Invalid error code returned by a driver for GL_ARRAY_BUFFER as mode"; 6158 } 6159 6160 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 6161 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f)); 6162 6163 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 6164 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 6165 getWindowHeight())); 6166 6167 return result.code(); 6168 } 6169 6170 virtual long Cleanup() 6171 { 6172 glDisableVertexAttribArray(0); 6173 glUseProgram(0); 6174 glDeleteProgram(_program); 6175 glDeleteVertexArrays(1, &_vao); 6176 glDeleteBuffers(1, &_buffer); 6177 glDeleteBuffers(1, &_bufferIndirect); 6178 return NO_ERROR; 6179 } 6180 6181private: 6182 GLuint _program; 6183 GLuint _vao, _buffer, _bufferIndirect; 6184}; 6185 6186template <typename api> 6187struct CNegativeInvalidModeElements : public DrawIndirectBase 6188{ 6189 virtual std::string Title() 6190 { 6191 return "Negative: invalid mode - glDrawElementsIndirect"; 6192 } 6193 6194 virtual std::string Purpose() 6195 { 6196 return "Verify that a driver sets error and no driver crash occurred"; 6197 } 6198 6199 virtual std::string Method() 6200 { 6201 return "Set invalid mode to glDrawElemenetsIndirect"; 6202 } 6203 6204 virtual std::string PassCriteria() 6205 { 6206 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 6207 } 6208 6209 virtual long Setup() 6210 { 6211 glClear(GL_COLOR_BUFFER_BIT); 6212 return NO_ERROR; 6213 } 6214 6215 virtual long Run() 6216 { 6217 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 6218 if (!_program) 6219 { 6220 return ERROR; 6221 } 6222 glUseProgram(_program); 6223 6224 CColorArray coords; 6225 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 6226 6227 glGenVertexArrays(1, &_vao); 6228 glBindVertexArray(_vao); 6229 6230 glGenBuffers(1, &_buffer); 6231 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 6232 6233 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 6234 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 6235 glEnableVertexAttribArray(0); 6236 6237 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 6238 indirectElements.count = static_cast<GLuint>(coords.size()); 6239 indirectElements.primCount = 1; 6240 6241 CElementArray elements(coords.size(), 0); 6242 for (size_t i = 0; i < elements.size(); ++i) 6243 { 6244 elements[i] = static_cast<GLuint>(i); 6245 } 6246 6247 glGenBuffers(1, &_bufferIndirect); 6248 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 6249 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW); 6250 6251 glGenBuffers(1, &_ebo); 6252 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 6253 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 6254 GL_STATIC_DRAW); 6255 6256 DIResult result; 6257 glDrawElementsIndirect(GL_INVALID_ENUM, GL_UNSIGNED_INT, 0); 6258 if (glGetError() != GL_INVALID_ENUM) 6259 { 6260 result.error() << "Invalid error code returned by a driver for GL_FLOAT as mode"; 6261 } 6262 6263 glDrawElementsIndirect(GL_UNSIGNED_INT, GL_UNSIGNED_INT, 0); 6264 if (glGetError() != GL_INVALID_ENUM) 6265 { 6266 result.error() << "Invalid error code returned by a driver for GL_UNSIGNED_INT as mode"; 6267 } 6268 6269 glDrawElementsIndirect(GL_ELEMENT_ARRAY_BUFFER, GL_UNSIGNED_INT, 0); 6270 if (glGetError() != GL_INVALID_ENUM) 6271 { 6272 result.error() << "Invalid error code returned by a driver for GL_ELEMENT_ARRAY_BUFFER as mode"; 6273 } 6274 6275 glDrawElementsIndirect(GL_FASTEST, GL_UNSIGNED_INT, 0); 6276 if (glGetError() != GL_INVALID_ENUM) 6277 { 6278 result.error() << "Invalid error code returned by a driver for GL_FASTEST as mode"; 6279 } 6280 6281 glDrawElementsIndirect(GL_PACK_ALIGNMENT, GL_UNSIGNED_INT, 0); 6282 if (glGetError() != GL_INVALID_ENUM) 6283 { 6284 result.error() << "Invalid error code returned by a driver for GL_PACK_ALIGNMENT as mode"; 6285 } 6286 6287 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 6288 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f)); 6289 6290 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 6291 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 6292 getWindowHeight())); 6293 6294 return result.code(); 6295 } 6296 6297 virtual long Cleanup() 6298 { 6299 glDisableVertexAttribArray(0); 6300 glUseProgram(0); 6301 glDeleteProgram(_program); 6302 glDeleteVertexArrays(1, &_vao); 6303 glDeleteBuffers(1, &_buffer); 6304 glDeleteBuffers(1, &_ebo); 6305 glDeleteBuffers(1, &_bufferIndirect); 6306 return NO_ERROR; 6307 } 6308 6309private: 6310 GLuint _program; 6311 GLuint _vao, _buffer, _ebo, _bufferIndirect; 6312}; 6313 6314template <typename api> 6315struct CNegativeNoVAOArrays : public DrawIndirectBase 6316{ 6317 virtual std::string Title() 6318 { 6319 return "Negative: no VAO - glDrawArraysIndirect"; 6320 } 6321 6322 virtual std::string Purpose() 6323 { 6324 return "Verify that a driver sets error and no driver crash occurred"; 6325 } 6326 6327 virtual std::string Method() 6328 { 6329 return "Use glDrawArraysIndirect with default VAO"; 6330 } 6331 6332 virtual std::string PassCriteria() 6333 { 6334 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 6335 } 6336 6337 virtual long Setup() 6338 { 6339 glClear(GL_COLOR_BUFFER_BIT); 6340 return NO_ERROR; 6341 } 6342 6343 virtual long Run() 6344 { 6345 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 6346 if (!_program) 6347 { 6348 return ERROR; 6349 } 6350 glUseProgram(_program); 6351 6352 CColorArray coords; 6353 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 6354 6355 glGenBuffers(1, &_buffer); 6356 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 6357 6358 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 6359 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 6360 glEnableVertexAttribArray(0); 6361 6362 DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 }; 6363 indirectArrays.count = static_cast<GLuint>(coords.size()); 6364 indirectArrays.primCount = 1; 6365 6366 glGenBuffers(1, &_bufferIndirect); 6367 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 6368 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectArrays, GL_STATIC_DRAW); 6369 6370 DIResult result; 6371 glDrawArraysIndirect(GL_TRIANGLES, 0); 6372 if (glGetError() != GL_INVALID_OPERATION) 6373 { 6374 result.error() << "Invalid error code returned by a driver"; 6375 } 6376 6377 if (glu::isContextTypeES(m_context.getRenderContext().getType())) 6378 glDisableVertexAttribArray(0); 6379 6380 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 6381 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f)); 6382 6383 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 6384 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 6385 getWindowHeight())); 6386 6387 return result.code(); 6388 } 6389 6390 virtual long Cleanup() 6391 { 6392 6393 if (glu::isContextTypeES(m_context.getRenderContext().getType())) 6394 glDisableVertexAttribArray(0); 6395 6396 glUseProgram(0); 6397 glDeleteProgram(_program); 6398 glDeleteBuffers(1, &_buffer); 6399 glDeleteBuffers(1, &_bufferIndirect); 6400 return NO_ERROR; 6401 } 6402 6403private: 6404 GLuint _program; 6405 GLuint _buffer, _ebo, _bufferIndirect; 6406}; 6407 6408template <typename api> 6409struct CNegativeNoVAOElements : public DrawIndirectBase 6410{ 6411 virtual std::string Title() 6412 { 6413 return "Negative: no VAO - glDrawElementsIndirect"; 6414 } 6415 6416 virtual std::string Purpose() 6417 { 6418 return "Verify that a driver sets error and no driver crash occurred"; 6419 } 6420 6421 virtual std::string Method() 6422 { 6423 return "Use glDrawElemenetsIndirect with default VAO"; 6424 } 6425 6426 virtual std::string PassCriteria() 6427 { 6428 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 6429 } 6430 6431 virtual long Setup() 6432 { 6433 glClear(GL_COLOR_BUFFER_BIT); 6434 return NO_ERROR; 6435 } 6436 6437 virtual long Run() 6438 { 6439 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 6440 if (!_program) 6441 { 6442 return ERROR; 6443 } 6444 glUseProgram(_program); 6445 6446 CColorArray coords; 6447 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 6448 6449 glGenBuffers(1, &_buffer); 6450 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 6451 6452 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 6453 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 6454 glEnableVertexAttribArray(0); 6455 6456 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 6457 indirectElements.count = static_cast<GLuint>(coords.size()); 6458 indirectElements.primCount = 1; 6459 6460 CElementArray elements(coords.size(), 0); 6461 for (size_t i = 0; i < elements.size(); ++i) 6462 { 6463 elements[i] = static_cast<GLuint>(i); 6464 } 6465 6466 glGenBuffers(1, &_bufferIndirect); 6467 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 6468 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW); 6469 6470 glGenBuffers(1, &_ebo); 6471 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 6472 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 6473 GL_STATIC_DRAW); 6474 6475 DIResult result; 6476 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0); 6477 if (glGetError() != GL_INVALID_OPERATION) 6478 { 6479 result.error() << "Invalid error code returned by a driver"; 6480 } 6481 6482 if (glu::isContextTypeES(m_context.getRenderContext().getType())) 6483 glDisableVertexAttribArray(0); 6484 6485 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 6486 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f)); 6487 6488 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 6489 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 6490 getWindowHeight())); 6491 6492 return result.code(); 6493 } 6494 6495 virtual long Cleanup() 6496 { 6497 glUseProgram(0); 6498 glDeleteProgram(_program); 6499 glDeleteBuffers(1, &_buffer); 6500 glDeleteBuffers(1, &_ebo); 6501 glDeleteBuffers(1, &_bufferIndirect); 6502 return NO_ERROR; 6503 } 6504 6505private: 6506 GLuint _program; 6507 GLuint _buffer, _ebo, _bufferIndirect; 6508}; 6509 6510template <typename api> 6511struct CNegativeNoVBOArrays : public DrawIndirectBase 6512{ 6513 virtual std::string Title() 6514 { 6515 return "Negative: no VBO - glDrawArraysIndirect"; 6516 } 6517 6518 virtual std::string Purpose() 6519 { 6520 return "Verify that a driver sets error and no driver crash occurred"; 6521 } 6522 6523 virtual std::string Method() 6524 { 6525 return "Use glDrawArraysIndirect with enabled vertex array, that has no VBO bound"; 6526 } 6527 6528 virtual std::string PassCriteria() 6529 { 6530 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 6531 } 6532 6533 virtual long Setup() 6534 { 6535 glClear(GL_COLOR_BUFFER_BIT); 6536 return NO_ERROR; 6537 } 6538 6539 virtual long Run() 6540 { 6541 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 6542 if (!_program) 6543 { 6544 return ERROR; 6545 } 6546 glUseProgram(_program); 6547 6548 CColorArray coords; 6549 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 6550 6551 glGenVertexArrays(1, &_vao); 6552 glBindVertexArray(_vao); 6553 glEnableVertexAttribArray(0); 6554 6555 DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 }; 6556 indirectArrays.count = static_cast<GLuint>(coords.size()); 6557 indirectArrays.primCount = 1; 6558 6559 glGenBuffers(1, &_bufferIndirect); 6560 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 6561 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectArrays, GL_STATIC_DRAW); 6562 6563 DIResult result; 6564 glDrawArraysIndirect(GL_TRIANGLES, 0); 6565 if (glGetError() != GL_INVALID_OPERATION) 6566 { 6567 result.error() << "Invalid error code returned by a driver"; 6568 } 6569 6570 glDisableVertexAttribArray(0); 6571 6572 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 6573 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f)); 6574 6575 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 6576 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 6577 getWindowHeight())); 6578 6579 return result.code(); 6580 } 6581 6582 virtual long Cleanup() 6583 { 6584 glDisableVertexAttribArray(0); 6585 glUseProgram(0); 6586 glDeleteProgram(_program); 6587 glDeleteVertexArrays(1, &_vao); 6588 glDeleteBuffers(1, &_bufferIndirect); 6589 return NO_ERROR; 6590 } 6591 6592private: 6593 GLuint _program; 6594 GLuint _vao, _ebo, _bufferIndirect; 6595}; 6596 6597template <typename api> 6598struct CNegativeNoVBOElements : public DrawIndirectBase 6599{ 6600 virtual std::string Title() 6601 { 6602 return "Negative: no VBO - glDrawElementsIndirect"; 6603 } 6604 6605 virtual std::string Purpose() 6606 { 6607 return "Verify that a driver sets error and no driver crash occurred"; 6608 } 6609 6610 virtual std::string Method() 6611 { 6612 return "Use glDrawElementsIndirect with enabled vertex array, that has no VBO bound"; 6613 } 6614 6615 virtual std::string PassCriteria() 6616 { 6617 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 6618 } 6619 6620 virtual long Setup() 6621 { 6622 glClear(GL_COLOR_BUFFER_BIT); 6623 return NO_ERROR; 6624 } 6625 6626 virtual long Run() 6627 { 6628 6629 api::ES_Only(); 6630 6631 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 6632 if (!_program) 6633 { 6634 return ERROR; 6635 } 6636 glUseProgram(_program); 6637 6638 CColorArray coords; 6639 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 6640 6641 glGenVertexArrays(1, &_vao); 6642 glBindVertexArray(_vao); 6643 glEnableVertexAttribArray(0); 6644 glEnableVertexAttribArray(0); 6645 6646 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 6647 indirectElements.count = static_cast<GLuint>(coords.size()); 6648 indirectElements.primCount = 1; 6649 6650 CElementArray elements(coords.size(), 0); 6651 for (size_t i = 0; i < elements.size(); ++i) 6652 { 6653 elements[i] = static_cast<GLuint>(i); 6654 } 6655 6656 glGenBuffers(1, &_bufferIndirect); 6657 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 6658 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW); 6659 6660 glGenBuffers(1, &_ebo); 6661 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 6662 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 6663 GL_STATIC_DRAW); 6664 6665 DIResult result; 6666 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0); 6667 if (glGetError() != GL_INVALID_OPERATION) 6668 { 6669 result.error() << "Invalid error code returned by a driver"; 6670 } 6671 6672 glDisableVertexAttribArray(0); 6673 6674 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 6675 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f)); 6676 6677 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 6678 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 6679 getWindowHeight())); 6680 6681 return result.code(); 6682 } 6683 6684 virtual long Cleanup() 6685 { 6686 glDisableVertexAttribArray(0); 6687 glUseProgram(0); 6688 glDeleteProgram(_program); 6689 glDeleteVertexArrays(1, &_vao); 6690 glDeleteBuffers(1, &_ebo); 6691 glDeleteBuffers(1, &_bufferIndirect); 6692 return NO_ERROR; 6693 } 6694 6695private: 6696 GLuint _program; 6697 GLuint _vao, _ebo, _bufferIndirect; 6698}; 6699 6700template <typename api> 6701struct CNegativeBufferMappedArray : public DrawIndirectBase 6702{ 6703 virtual std::string Title() 6704 { 6705 return "Negative: buffer mapped - glDrawArraysIndirect"; 6706 } 6707 6708 virtual std::string Purpose() 6709 { 6710 return "Verify that a driver sets error and no driver crash occurred"; 6711 } 6712 6713 virtual std::string Method() 6714 { 6715 return "1. Create and bind buffer" NL "2. Map buffer" NL "3. Call glDrawArrayIndirect"; 6716 } 6717 6718 virtual std::string PassCriteria() 6719 { 6720 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 6721 } 6722 6723 virtual long Setup() 6724 { 6725 glClear(GL_COLOR_BUFFER_BIT); 6726 return NO_ERROR; 6727 } 6728 6729 virtual long Run() 6730 { 6731 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 6732 if (!_program) 6733 { 6734 return ERROR; 6735 } 6736 glUseProgram(_program); 6737 6738 CColorArray coords; 6739 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 6740 6741 glGenVertexArrays(1, &_vao); 6742 glBindVertexArray(_vao); 6743 6744 glGenBuffers(1, &_buffer); 6745 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 6746 6747 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 6748 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 6749 glEnableVertexAttribArray(0); 6750 6751 DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 }; 6752 indirectArrays.count = static_cast<GLuint>(coords.size()); 6753 indirectArrays.primCount = 1; 6754 6755 glGenBuffers(1, &_bufferIndirect); 6756 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 6757 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW); 6758 6759 DIResult result; 6760 void* buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawArraysIndirectCommand), GL_MAP_READ_BIT); 6761 if (buf == 0) 6762 { 6763 result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_MAP_READ_BIT) returned NULL"; 6764 } 6765 6766 glDrawArraysIndirect(GL_TRIANGLES, 0); 6767 6768 GLenum error = glGetError(); 6769 if (error == GL_INVALID_OPERATION) 6770 { 6771 //GL error: nothing is rendered 6772 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 6773 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f)); 6774 6775 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 6776 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, 6777 getWindowWidth(), getWindowHeight())); 6778 } 6779 else if (error == GL_NO_ERROR) 6780 { 6781 //No GL error: undefined 6782 } 6783 else 6784 { 6785 result.error() << "Invalid error code returned by a driver"; 6786 } 6787 6788 if (buf) 6789 { 6790 if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) != GL_TRUE) 6791 { 6792 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE"; 6793 } 6794 buf = 0; 6795 } 6796 6797 return result.code(); 6798 } 6799 6800 virtual long Cleanup() 6801 { 6802 glDisableVertexAttribArray(0); 6803 glUseProgram(0); 6804 glDeleteProgram(_program); 6805 glDeleteVertexArrays(1, &_vao); 6806 glDeleteBuffers(1, &_buffer); 6807 glDeleteBuffers(1, &_bufferIndirect); 6808 return NO_ERROR; 6809 } 6810 6811private: 6812 GLuint _program; 6813 GLuint _vao, _buffer, _bufferIndirect; 6814}; 6815 6816template <typename api> 6817struct CNegativeBufferMappedElements : public DrawIndirectBase 6818{ 6819 virtual std::string Title() 6820 { 6821 return "Negative: buffer mapped - glDrawElementsIndirect"; 6822 } 6823 6824 virtual std::string Purpose() 6825 { 6826 return "Verify that a driver sets error and no driver crash occurred"; 6827 } 6828 6829 virtual std::string Method() 6830 { 6831 return "1. Create and bind buffer" NL "2. Map buffer" NL "3. Call glDrawElementsIndirect"; 6832 } 6833 6834 virtual std::string PassCriteria() 6835 { 6836 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 6837 } 6838 6839 virtual long Setup() 6840 { 6841 glClear(GL_COLOR_BUFFER_BIT); 6842 return NO_ERROR; 6843 } 6844 6845 virtual long Run() 6846 { 6847 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 6848 if (!_program) 6849 { 6850 return ERROR; 6851 } 6852 glUseProgram(_program); 6853 6854 CColorArray coords; 6855 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 6856 6857 glGenVertexArrays(1, &_vao); 6858 glBindVertexArray(_vao); 6859 6860 glGenBuffers(1, &_buffer); 6861 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 6862 6863 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 6864 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 6865 glEnableVertexAttribArray(0); 6866 6867 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 6868 indirectElements.count = static_cast<GLuint>(coords.size()); 6869 indirectElements.primCount = 1; 6870 6871 CElementArray elements(coords.size(), 0); 6872 for (size_t i = 0; i < elements.size(); ++i) 6873 { 6874 elements[i] = static_cast<GLuint>(i); 6875 } 6876 6877 glGenBuffers(1, &_bufferIndirect); 6878 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 6879 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW); 6880 6881 glGenBuffers(1, &_ebo); 6882 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 6883 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 6884 GL_STATIC_DRAW); 6885 6886 DIResult result; 6887 void* buf = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, sizeof(DrawElementsIndirectCommand), GL_MAP_WRITE_BIT); 6888 if (buf == 0) 6889 { 6890 result.error() << "glMapBuffer(GL_DRAW_INDIRECT_BUFFER, GL_MAP_WRITE_BIT) returned NULL"; 6891 } 6892 6893 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0); 6894 6895 GLenum error = glGetError(); 6896 if (error == GL_INVALID_OPERATION) 6897 { 6898 //GL error: nothing is rendered 6899 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 6900 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f)); 6901 6902 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 6903 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, 6904 getWindowWidth(), getWindowHeight())); 6905 } 6906 else if (error == GL_NO_ERROR) 6907 { 6908 //No GL error: undefined 6909 } 6910 else 6911 { 6912 result.error() << "Invalid error code returned by a driver"; 6913 } 6914 6915 if (buf) 6916 { 6917 if (glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) != GL_TRUE) 6918 { 6919 result.error() << "glUnmapBuffer(GL_DRAW_INDIRECT_BUFFER) returned GL_FALSE, expected GL_TRUE"; 6920 } 6921 buf = 0; 6922 } 6923 6924 return result.code(); 6925 } 6926 6927 virtual long Cleanup() 6928 { 6929 glDisableVertexAttribArray(0); 6930 glUseProgram(0); 6931 glDeleteProgram(_program); 6932 glDeleteVertexArrays(1, &_vao); 6933 glDeleteBuffers(1, &_buffer); 6934 glDeleteBuffers(1, &_ebo); 6935 glDeleteBuffers(1, &_bufferIndirect); 6936 return NO_ERROR; 6937 } 6938 6939private: 6940 GLuint _program; 6941 GLuint _vao, _buffer, _ebo, _bufferIndirect; 6942}; 6943 6944template <typename api> 6945struct CNegativeDataWrongElements : public DrawIndirectBase 6946{ 6947 virtual std::string Title() 6948 { 6949 return "Negative: invalid type - glDrawElementsIndirect"; 6950 } 6951 6952 virtual std::string Purpose() 6953 { 6954 return "Verify that a driver sets error and no driver crash occurred"; 6955 } 6956 6957 virtual std::string Method() 6958 { 6959 return "1. Bind non-zero buffer" NL "2. Call glDrawElementsIndirect with invalid type"; 6960 } 6961 6962 virtual std::string PassCriteria() 6963 { 6964 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 6965 } 6966 6967 virtual long Setup() 6968 { 6969 glClear(GL_COLOR_BUFFER_BIT); 6970 return NO_ERROR; 6971 } 6972 6973 virtual long Run() 6974 { 6975 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 6976 if (!_program) 6977 { 6978 return ERROR; 6979 } 6980 glUseProgram(_program); 6981 6982 CColorArray coords; 6983 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 6984 6985 glGenVertexArrays(1, &_vao); 6986 glBindVertexArray(_vao); 6987 6988 glGenBuffers(1, &_buffer); 6989 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 6990 6991 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 6992 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 6993 glEnableVertexAttribArray(0); 6994 6995 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 6996 indirectElements.count = static_cast<GLuint>(coords.size()); 6997 indirectElements.primCount = 1; 6998 6999 CElementArray elements(coords.size(), 0); 7000 for (size_t i = 0; i < elements.size(); ++i) 7001 { 7002 elements[i] = static_cast<GLuint>(i); 7003 } 7004 7005 glGenBuffers(1, &_bufferIndirect); 7006 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 7007 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW); 7008 7009 glGenBuffers(1, &_ebo); 7010 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 7011 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 7012 GL_STATIC_DRAW); 7013 7014 DIResult result; 7015 7016 glDrawElementsIndirect(GL_TRIANGLES, GL_FLOAT, 0); 7017 if (glGetError() != GL_INVALID_ENUM) 7018 { 7019 result.error() << "Invalid error code returned by a driver for GL_FLOAT type"; 7020 } 7021 7022 glDrawElementsIndirect(GL_TRIANGLES, GL_INT, 0); 7023 if (glGetError() != GL_INVALID_ENUM) 7024 { 7025 result.error() << "Invalid error code returned by a driver for GL_INT type"; 7026 } 7027 7028 glDrawElementsIndirect(GL_TRIANGLES, GL_STATIC_DRAW, 0); 7029 if (glGetError() != GL_INVALID_ENUM) 7030 { 7031 result.error() << "Invalid error code returned by a driver for GL_STATIC_DRAW type"; 7032 } 7033 7034 glDrawElementsIndirect(GL_TRIANGLES, GL_SHORT, 0); 7035 if (glGetError() != GL_INVALID_ENUM) 7036 { 7037 result.error() << "Invalid error code returned by a driver for GL_SHORT type"; 7038 } 7039 7040 glDrawElementsIndirect(GL_TRIANGLES, GL_BYTE, 0); 7041 if (glGetError() != GL_INVALID_ENUM) 7042 { 7043 result.error() << "Invalid error code returned by a driver for GL_BYTE type"; 7044 } 7045 7046 glDrawElementsIndirect(GL_TRIANGLES, GL_DOUBLE, 0); 7047 if (glGetError() != GL_INVALID_ENUM) 7048 { 7049 result.error() << "Invalid error code returned by a driver for GL_DOUBLE type"; 7050 } 7051 7052 glDrawElementsIndirect(GL_TRIANGLES, GL_INVALID_ENUM, 0); 7053 if (glGetError() != GL_INVALID_ENUM) 7054 { 7055 result.error() << "Invalid error code returned by a driver for GL_INVALID_ENUM type"; 7056 } 7057 7058 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 7059 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f)); 7060 7061 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 7062 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 7063 getWindowHeight())); 7064 7065 return result.code(); 7066 } 7067 7068 virtual long Cleanup() 7069 { 7070 glDisableVertexAttribArray(0); 7071 glUseProgram(0); 7072 glDeleteProgram(_program); 7073 glDeleteVertexArrays(1, &_vao); 7074 glDeleteBuffers(1, &_buffer); 7075 glDeleteBuffers(1, &_ebo); 7076 glDeleteBuffers(1, &_bufferIndirect); 7077 return NO_ERROR; 7078 } 7079 7080private: 7081 GLuint _program; 7082 GLuint _vao, _buffer, _ebo, _bufferIndirect; 7083}; 7084 7085template <typename api> 7086class CNegativeGshArray : public DrawIndirectBase 7087{ 7088public: 7089 virtual std::string Title() 7090 { 7091 return "Negative: incompatible the input primitive type of gsh - glDrawArrayIndirect"; 7092 } 7093 7094 virtual std::string Purpose() 7095 { 7096 return "Verify that a driver sets error and no driver crash occurred"; 7097 } 7098 7099 virtual std::string Method() 7100 { 7101 return "1. Bind non-zero buffer" NL "2. Set data" NL "3. Set wrong geometry shader" NL 7102 "4. Call glDrawArrayIndirect"; 7103 } 7104 7105 virtual std::string PassCriteria() 7106 { 7107 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 7108 } 7109 7110 virtual long Setup() 7111 { 7112 glClear(GL_COLOR_BUFFER_BIT); 7113 return NO_ERROR; 7114 } 7115 7116 virtual long Run() 7117 { 7118 _program = CreateProgram(Vsh(), Gsh(), Fsh(), true); 7119 if (!_program) 7120 { 7121 return ERROR; 7122 } 7123 glUseProgram(_program); 7124 7125 CColorArray coords; 7126 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 7127 7128 glGenVertexArrays(1, &_vao); 7129 glBindVertexArray(_vao); 7130 7131 glGenBuffers(1, &_buffer); 7132 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 7133 7134 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 7135 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 7136 glEnableVertexAttribArray(0); 7137 7138 DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 }; 7139 indirectArrays.count = static_cast<GLuint>(coords.size()); 7140 indirectArrays.primCount = 1; 7141 indirectArrays.first = 0; 7142 indirectArrays.reservedMustBeZero = 2312; 7143 7144 glGenBuffers(1, &_bufferIndirect); 7145 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 7146 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW); 7147 7148 DIResult result; 7149 7150 glDrawArraysIndirect(GL_POINTS, 0); 7151 if (glGetError() != GL_INVALID_OPERATION) 7152 { 7153 result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type"; 7154 } 7155 7156 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 7157 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f)); 7158 7159 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 7160 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 7161 getWindowHeight())); 7162 7163 return result.code(); 7164 } 7165 7166 virtual long Cleanup() 7167 { 7168 glDisableVertexAttribArray(0); 7169 glUseProgram(0); 7170 glDeleteProgram(_program); 7171 glDeleteVertexArrays(1, &_vao); 7172 glDeleteBuffers(1, &_buffer); 7173 glDeleteBuffers(1, &_bufferIndirect); 7174 return NO_ERROR; 7175 } 7176 7177private: 7178 std::string Vsh() 7179 { 7180 return "#version 150" NL "in vec4 coords;" NL "void main() {" NL " gl_Position = coords;" NL "}"; 7181 } 7182 7183 std::string Gsh() 7184 { 7185 return "#version 150" NL "layout(triangles) in;" NL "layout(triangle_strip, max_vertices = 10) out;" NL 7186 "void main() {" NL " for (int i=0; i<gl_in.length(); ++i) {" NL 7187 " gl_Position = gl_in[i].gl_Position;" NL " EmitVertex();" NL " }" NL "}"; 7188 } 7189 7190 std::string Fsh() 7191 { 7192 return "#version 140" NL "out vec4 outColor;" NL "void main() {" NL 7193 " outColor = vec4(0.1f, 0.2f, 0.3f, 1.0f);" NL "}"; 7194 } 7195 GLuint _program; 7196 GLuint _vao, _buffer, _bufferIndirect; 7197}; 7198 7199template <typename api> 7200class CNegativeGshElements : public DrawIndirectBase 7201{ 7202public: 7203 virtual std::string Title() 7204 { 7205 return "Negative: incompatible the input primitive type of gsh - glDrawElementsIndirect"; 7206 } 7207 7208 virtual std::string Purpose() 7209 { 7210 return "Verify that a driver sets error and no driver crash occurred"; 7211 } 7212 7213 virtual std::string Method() 7214 { 7215 return "1. Bind non-zero buffer" NL "2. Set data" NL "3. Set wrong geometry shader" NL 7216 "4. Call glDrawElementsIndirect"; 7217 } 7218 7219 virtual std::string PassCriteria() 7220 { 7221 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 7222 } 7223 7224 virtual long Setup() 7225 { 7226 glClear(GL_COLOR_BUFFER_BIT); 7227 return NO_ERROR; 7228 } 7229 7230 virtual long Run() 7231 { 7232 _program = CreateProgram(Vsh(), Gsh(), Fsh(), true); 7233 if (!_program) 7234 { 7235 return ERROR; 7236 } 7237 glUseProgram(_program); 7238 7239 CColorArray coords; 7240 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 7241 7242 glGenVertexArrays(1, &_vao); 7243 glBindVertexArray(_vao); 7244 7245 glGenBuffers(1, &_buffer); 7246 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 7247 7248 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 7249 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 7250 glEnableVertexAttribArray(0); 7251 7252 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 7253 indirectElements.count = static_cast<GLuint>(coords.size()); 7254 indirectElements.primCount = 1; 7255 7256 CElementArray elements(coords.size(), 0); 7257 for (size_t i = 0; i < elements.size(); ++i) 7258 { 7259 elements[i] = static_cast<GLuint>(i); 7260 } 7261 7262 glGenBuffers(1, &_bufferIndirect); 7263 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 7264 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW); 7265 7266 glGenBuffers(1, &_ebo); 7267 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 7268 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 7269 GL_STATIC_DRAW); 7270 7271 DIResult result; 7272 7273 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0); 7274 if (glGetError() != GL_INVALID_OPERATION) 7275 { 7276 result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type"; 7277 } 7278 7279 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 7280 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f)); 7281 7282 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 7283 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 7284 getWindowHeight())); 7285 7286 return result.code(); 7287 } 7288 7289 virtual long Cleanup() 7290 { 7291 glDisableVertexAttribArray(0); 7292 glUseProgram(0); 7293 glDeleteProgram(_program); 7294 glDeleteVertexArrays(1, &_vao); 7295 glDeleteBuffers(1, &_buffer); 7296 glDeleteBuffers(1, &_ebo); 7297 glDeleteBuffers(1, &_bufferIndirect); 7298 return NO_ERROR; 7299 } 7300 7301private: 7302 std::string Vsh() 7303 { 7304 return "#version 150" NL "in vec4 coords;" NL "void main() {" NL " gl_Position = coords;" NL "}"; 7305 } 7306 7307 std::string Gsh() 7308 { 7309 return "#version 150" NL "layout(lines) in;" NL "layout(line_strip, max_vertices = 10) out;" NL 7310 "void main() {" NL " for (int i=0; i<gl_in.length(); ++i) {" NL 7311 " gl_Position = gl_in[i].gl_Position;" NL " EmitVertex();" NL " }" NL "}"; 7312 } 7313 7314 std::string Fsh() 7315 { 7316 return "#version 140" NL "out vec4 outColor;" NL "void main() {" NL 7317 " outColor = vec4(0.1f, 0.2f, 0.3f, 1.0f);" NL "}"; 7318 } 7319 int _program; 7320 GLuint _vao, _buffer, _ebo, _bufferIndirect; 7321}; 7322 7323template <typename api> 7324struct CNegativeInvalidSizeArrays : public DrawIndirectBase 7325{ 7326 struct TWrongStructure1 7327 { 7328 GLuint count; 7329 GLuint primCount; 7330 }; 7331 7332 struct TWrongStructure2 7333 { 7334 GLfloat count; 7335 GLuint primCount; 7336 }; 7337 7338 virtual std::string Title() 7339 { 7340 return "Negative: wrong structure - glDrawArrayIndirect"; 7341 } 7342 7343 virtual std::string Purpose() 7344 { 7345 return "Verify that a driver sets error and no driver crash occurred"; 7346 } 7347 7348 virtual std::string Method() 7349 { 7350 return "Call glDrawArrayIndirect with wrong structure"; 7351 } 7352 7353 virtual std::string PassCriteria() 7354 { 7355 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 7356 } 7357 7358 virtual long Setup() 7359 { 7360 glClear(GL_COLOR_BUFFER_BIT); 7361 return NO_ERROR; 7362 } 7363 7364 virtual long Run() 7365 { 7366 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 7367 if (!_program) 7368 { 7369 return ERROR; 7370 } 7371 glUseProgram(_program); 7372 7373 CColorArray coords; 7374 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 7375 7376 glGenVertexArrays(1, &_vao); 7377 glBindVertexArray(_vao); 7378 7379 glGenBuffers(1, &_buffer); 7380 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 7381 7382 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 7383 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 7384 glEnableVertexAttribArray(0); 7385 7386 TWrongStructure1 indirectArrays = { 0, 0 }; 7387 indirectArrays.count = static_cast<GLuint>(coords.size()); 7388 indirectArrays.primCount = 1; 7389 7390 glGenBuffers(1, &_bufferIndirect); 7391 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 7392 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(TWrongStructure1), &indirectArrays, GL_STATIC_DRAW); 7393 7394 DIResult result; 7395 7396 glDrawArraysIndirect(GL_TRIANGLES, 0); 7397 if (glGetError() != GL_INVALID_OPERATION) 7398 { 7399 result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type"; 7400 } 7401 7402 glDeleteBuffers(1, &_bufferIndirect); 7403 7404 TWrongStructure2 indirectArrays2 = { 0, 0 }; 7405 indirectArrays2.count = static_cast<GLfloat>(coords.size()); 7406 indirectArrays2.primCount = 1; 7407 7408 glGenBuffers(1, &_bufferIndirect); 7409 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 7410 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(TWrongStructure2), &indirectArrays2, GL_STATIC_DRAW); 7411 7412 glDrawArraysIndirect(GL_TRIANGLES, 0); 7413 if (glGetError() != GL_INVALID_OPERATION) 7414 { 7415 result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type"; 7416 } 7417 7418 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 7419 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f)); 7420 7421 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 7422 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 7423 getWindowHeight())); 7424 7425 return result.code(); 7426 } 7427 7428 virtual long Cleanup() 7429 { 7430 glDisableVertexAttribArray(0); 7431 glUseProgram(0); 7432 glDeleteProgram(_program); 7433 glDeleteVertexArrays(1, &_vao); 7434 glDeleteBuffers(1, &_buffer); 7435 glDeleteBuffers(1, &_bufferIndirect); 7436 return NO_ERROR; 7437 } 7438 7439private: 7440 GLuint _program; 7441 GLuint _vao, _buffer, _bufferIndirect; 7442}; 7443 7444template <typename api> 7445struct CNegativeInvalidSizeElements : public DrawIndirectBase 7446{ 7447 struct TWrongStructure 7448 { 7449 GLfloat count; 7450 GLuint primCount; 7451 }; 7452 7453 virtual std::string Title() 7454 { 7455 return "Negative: wrong structure - glDrawElementsIndirect"; 7456 } 7457 7458 virtual std::string Purpose() 7459 { 7460 return "Verify that a driver sets error and no driver crash occurred"; 7461 } 7462 7463 virtual std::string Method() 7464 { 7465 return "Call glDrawElementsIndirect with wrong structure"; 7466 } 7467 7468 virtual std::string PassCriteria() 7469 { 7470 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 7471 } 7472 7473 virtual long Setup() 7474 { 7475 glClear(GL_COLOR_BUFFER_BIT); 7476 return NO_ERROR; 7477 } 7478 7479 virtual long Run() 7480 { 7481 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 7482 if (!_program) 7483 { 7484 return ERROR; 7485 } 7486 glUseProgram(_program); 7487 7488 CColorArray coords; 7489 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 7490 7491 glGenVertexArrays(1, &_vao); 7492 glBindVertexArray(_vao); 7493 7494 glGenBuffers(1, &_buffer); 7495 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 7496 7497 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 7498 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 7499 glEnableVertexAttribArray(0); 7500 7501 DrawArraysIndirectCommand indirectElements = { 0, 0, 0, 0 }; 7502 indirectElements.count = static_cast<GLuint>(coords.size()); 7503 indirectElements.primCount = 1; 7504 7505 CElementArray elements(coords.size(), 0); 7506 for (size_t i = 0; i < elements.size(); ++i) 7507 { 7508 elements[i] = static_cast<GLuint>(i); 7509 } 7510 7511 glGenBuffers(1, &_bufferIndirect); 7512 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 7513 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectElements, GL_STATIC_DRAW); 7514 7515 glGenBuffers(1, &_ebo); 7516 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 7517 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 7518 GL_STATIC_DRAW); 7519 7520 DIResult result; 7521 7522 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0); 7523 if (glGetError() != GL_INVALID_OPERATION) 7524 { 7525 result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type"; 7526 } 7527 7528 TWrongStructure indirectElements2 = { 0, 0 }; 7529 indirectElements2.count = static_cast<GLfloat>(coords.size()); 7530 indirectElements2.primCount = 1; 7531 7532 glDeleteBuffers(1, &_bufferIndirect); 7533 glGenBuffers(1, &_bufferIndirect); 7534 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 7535 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(TWrongStructure), &indirectElements2, GL_STATIC_DRAW); 7536 7537 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0); 7538 if (glGetError() != GL_INVALID_OPERATION) 7539 { 7540 result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type"; 7541 } 7542 7543 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 7544 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f)); 7545 7546 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 7547 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 7548 getWindowHeight())); 7549 7550 return result.code(); 7551 } 7552 7553 virtual long Cleanup() 7554 { 7555 glDisableVertexAttribArray(0); 7556 glUseProgram(0); 7557 glDeleteProgram(_program); 7558 glDeleteVertexArrays(1, &_vao); 7559 glDeleteBuffers(1, &_buffer); 7560 glDeleteBuffers(1, &_ebo); 7561 glDeleteBuffers(1, &_bufferIndirect); 7562 return NO_ERROR; 7563 } 7564 7565private: 7566 GLuint _program; 7567 GLuint _vao, _buffer, _ebo, _bufferIndirect; 7568}; 7569 7570template <typename api> 7571struct CNegativeStructureWrongOffsetArray : public DrawIndirectBase 7572{ 7573 virtual std::string Title() 7574 { 7575 return "Negative: wrong offset - glDrawArrayIndirect"; 7576 } 7577 7578 virtual std::string Purpose() 7579 { 7580 return "Verify that a driver sets error and no driver crash occurred"; 7581 } 7582 7583 virtual std::string Method() 7584 { 7585 return "Call glDrawArrayIndirect with wrong offset"; 7586 } 7587 7588 virtual std::string PassCriteria() 7589 { 7590 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 7591 } 7592 7593 virtual long Setup() 7594 { 7595 glClear(GL_COLOR_BUFFER_BIT); 7596 return NO_ERROR; 7597 } 7598 7599 virtual long Run() 7600 { 7601 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 7602 if (!_program) 7603 { 7604 return ERROR; 7605 } 7606 glUseProgram(_program); 7607 7608 CColorArray coords; 7609 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 7610 7611 glGenVertexArrays(1, &_vao); 7612 glBindVertexArray(_vao); 7613 7614 glGenBuffers(1, &_buffer); 7615 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 7616 7617 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 7618 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 7619 glEnableVertexAttribArray(0); 7620 7621 DrawArraysIndirectCommand indirectArrays = { 0, 0, 0, 0 }; 7622 indirectArrays.count = static_cast<GLuint>(coords.size()); 7623 indirectArrays.primCount = 1; 7624 7625 glGenBuffers(1, &_bufferIndirect); 7626 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 7627 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawArraysIndirectCommand), &indirectArrays, GL_STATIC_DRAW); 7628 7629 DIResult result; 7630 7631 glDrawArraysIndirect(GL_TRIANGLES, (void*)(sizeof(DrawArraysIndirectCommand) * 2)); 7632 if (glGetError() != GL_INVALID_OPERATION) 7633 { 7634 result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type"; 7635 } 7636 7637 glDrawArraysIndirect(GL_TRIANGLES, (void*)(sizeof(GLuint))); 7638 if (glGetError() != GL_INVALID_OPERATION) 7639 { 7640 result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type"; 7641 } 7642 7643 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 7644 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f)); 7645 7646 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 7647 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 7648 getWindowHeight())); 7649 7650 return result.code(); 7651 } 7652 7653 virtual long Cleanup() 7654 { 7655 glDisableVertexAttribArray(0); 7656 glUseProgram(0); 7657 glDeleteProgram(_program); 7658 glDeleteVertexArrays(1, &_vao); 7659 glDeleteBuffers(1, &_buffer); 7660 glDeleteBuffers(1, &_bufferIndirect); 7661 return NO_ERROR; 7662 } 7663 7664private: 7665 GLuint _program; 7666 GLuint _vao, _buffer, _bufferIndirect; 7667}; 7668 7669template <typename api> 7670struct CNegativeStructureWrongOffsetElements : public DrawIndirectBase 7671{ 7672 virtual std::string Title() 7673 { 7674 return "Negative: wrong offset - glDrawElementsIndirect"; 7675 } 7676 7677 virtual std::string Purpose() 7678 { 7679 return "Verify that a driver sets error and no driver crash occurred"; 7680 } 7681 7682 virtual std::string Method() 7683 { 7684 return "Call glDrawElementsIndirect with wrong structure"; 7685 } 7686 7687 virtual std::string PassCriteria() 7688 { 7689 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 7690 } 7691 7692 virtual long Setup() 7693 { 7694 glClear(GL_COLOR_BUFFER_BIT); 7695 return NO_ERROR; 7696 } 7697 7698 virtual long Run() 7699 { 7700 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 7701 if (!_program) 7702 { 7703 return ERROR; 7704 } 7705 glUseProgram(_program); 7706 7707 CColorArray coords; 7708 PrimitiveGen(GL_TRIANGLES, 8, 8, coords); 7709 7710 glGenVertexArrays(1, &_vao); 7711 glBindVertexArray(_vao); 7712 7713 glGenBuffers(1, &_buffer); 7714 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 7715 7716 glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)(coords.size() * sizeof(coords[0])), &coords[0], GL_STREAM_DRAW); 7717 glVertexAttribPointer(0, sizeof(coords[0]) / sizeof(float), GL_FLOAT, GL_FALSE, sizeof(coords[0]), 0); 7718 glEnableVertexAttribArray(0); 7719 7720 DrawElementsIndirectCommand indirectElements = { 0, 0, 0, 0, 0 }; 7721 indirectElements.count = static_cast<GLuint>(coords.size()); 7722 indirectElements.primCount = 1; 7723 7724 CElementArray elements(coords.size(), 0); 7725 for (size_t i = 0; i < elements.size(); ++i) 7726 { 7727 elements[i] = static_cast<GLuint>(i); 7728 } 7729 7730 glGenBuffers(1, &_bufferIndirect); 7731 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 7732 glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawElementsIndirectCommand), &indirectElements, GL_STATIC_DRAW); 7733 7734 glGenBuffers(1, &_ebo); 7735 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 7736 glBufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)(elements.size() * sizeof(elements[0])), &elements[0], 7737 GL_STATIC_DRAW); 7738 7739 DIResult result; 7740 7741 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (void*)(sizeof(DrawElementsIndirectCommand) * 2)); 7742 if (glGetError() != GL_INVALID_OPERATION) 7743 { 7744 result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type"; 7745 } 7746 7747 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, (void*)(sizeof(GLuint))); 7748 if (glGetError() != GL_INVALID_OPERATION) 7749 { 7750 result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type"; 7751 } 7752 7753 CColorArray bufferRef(getWindowWidth() * getWindowHeight(), tcu::Vec4(0.0f)); 7754 CColorArray bufferTest(getWindowWidth() * getWindowHeight(), tcu::Vec4(1.0f)); 7755 7756 ReadPixelsFloat<api>(0, 0, getWindowWidth(), getWindowHeight(), &bufferTest[0]); 7757 result.sub_result(BuffersCompare(bufferTest, getWindowWidth(), getWindowHeight(), bufferRef, getWindowWidth(), 7758 getWindowHeight())); 7759 7760 return result.code(); 7761 } 7762 7763 virtual long Cleanup() 7764 { 7765 glDisableVertexAttribArray(0); 7766 glUseProgram(0); 7767 glDeleteProgram(_program); 7768 glDeleteVertexArrays(1, &_vao); 7769 glDeleteBuffers(1, &_buffer); 7770 glDeleteBuffers(1, &_ebo); 7771 glDeleteBuffers(1, &_bufferIndirect); 7772 return NO_ERROR; 7773 } 7774 7775private: 7776 GLuint _program; 7777 GLuint _vao, _buffer, _ebo, _bufferIndirect; 7778}; 7779 7780template <typename api> 7781struct CNegativeUnalignedOffset : public DrawIndirectBase 7782{ 7783 virtual std::string Title() 7784 { 7785 return "Negative: unaligned offset - glDrawElementsIndirect and glDrawArraysIndirect"; 7786 } 7787 7788 virtual std::string Purpose() 7789 { 7790 return "Verify that a driver sets error and no system/driver crash occurred"; 7791 } 7792 7793 virtual std::string Method() 7794 { 7795 return "Call with unaligned offset (1, 3, 1023)"; 7796 } 7797 7798 virtual std::string PassCriteria() 7799 { 7800 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 7801 } 7802 7803 virtual long Run() 7804 { 7805 _program = CreateProgram(shaders::vshSimple<api>(), "", shaders::fshSimple<api>(), true); 7806 if (!_program) 7807 { 7808 return ERROR; 7809 } 7810 glUseProgram(_program); 7811 7812 glGenVertexArrays(1, &_vao); 7813 glBindVertexArray(_vao); 7814 7815 std::vector<GLuint> zarro(4096, 0); 7816 7817 glGenBuffers(1, &_buffer); 7818 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 7819 glBufferData(GL_ARRAY_BUFFER, 4096, &zarro[0], GL_STREAM_DRAW); 7820 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); 7821 glEnableVertexAttribArray(0); 7822 7823 glGenBuffers(1, &_bufferIndirect); 7824 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 7825 glBufferData(GL_DRAW_INDIRECT_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW); 7826 7827 glGenBuffers(1, &_ebo); 7828 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 7829 glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW); 7830 7831 DIResult result; 7832 7833 int offsets[] = { 1, 3, 1023 }; 7834 for (size_t i = 0; i < sizeof(offsets) / sizeof(offsets[0]); i++) 7835 { 7836 glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, reinterpret_cast<void*>((deUintptr)offsets[i])); 7837 if (glGetError() != GL_INVALID_VALUE) 7838 { 7839 result.error() << "Invalid error code returned by a driver for GL_INVALID_VALUE type"; 7840 } 7841 glDrawArraysIndirect(GL_TRIANGLES, reinterpret_cast<void*>((deUintptr)offsets[i])); 7842 if (glGetError() != GL_INVALID_VALUE) 7843 { 7844 result.error() << "Invalid error code returned by a driver for GL_INVALID_VALUE type"; 7845 } 7846 } 7847 7848 return result.code(); 7849 } 7850 7851 virtual long Cleanup() 7852 { 7853 glDisableVertexAttribArray(0); 7854 glUseProgram(0); 7855 glDeleteProgram(_program); 7856 glDeleteVertexArrays(1, &_vao); 7857 glDeleteBuffers(1, &_buffer); 7858 glDeleteBuffers(1, &_ebo); 7859 glDeleteBuffers(1, &_bufferIndirect); 7860 return NO_ERROR; 7861 } 7862 7863private: 7864 GLuint _program; 7865 GLuint _vao, _buffer, _ebo, _bufferIndirect; 7866}; 7867 7868template <typename api> 7869struct CNegativeXFB : public DrawIndirectBase 7870{ 7871 virtual std::string Title() 7872 { 7873 return "Negative: transform feedback active and not paused - glDrawElementsIndirect and glDrawArraysIndirect"; 7874 } 7875 7876 virtual std::string Purpose() 7877 { 7878 return "Verify that a driver sets error and no system/driver crash occurred"; 7879 } 7880 7881 virtual std::string Method() 7882 { 7883 return "Call with transform feedback active"; 7884 } 7885 7886 virtual std::string PassCriteria() 7887 { 7888 return "The test will pass if OpenGL errors reported and no driver crash occurred"; 7889 } 7890 7891 virtual long Run() 7892 { 7893 api::ES_Only(); 7894 7895 bool drawWithXFBAllowed = m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"); 7896 7897 _program = CreateProgram(Vsh(), "", shaders::fshSimple<api>(), false); 7898 const GLchar* varyings[] = { "dataOut" }; 7899 glTransformFeedbackVaryings(_program, 1, varyings, GL_INTERLEAVED_ATTRIBS); 7900 glLinkProgram(_program); 7901 if (!CheckProgram(_program)) 7902 { 7903 return ERROR; 7904 } 7905 glUseProgram(_program); 7906 7907 glGenVertexArrays(1, &_vao); 7908 glBindVertexArray(_vao); 7909 7910 std::vector<GLuint> zarro(4096, 0); 7911 7912 glGenBuffers(1, &_buffer); 7913 glBindBuffer(GL_ARRAY_BUFFER, _buffer); 7914 glBufferData(GL_ARRAY_BUFFER, 4096, &zarro[0], GL_STREAM_DRAW); 7915 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); 7916 glEnableVertexAttribArray(0); 7917 7918 glGenBuffers(1, &_bufferIndirect); 7919 glBindBuffer(GL_DRAW_INDIRECT_BUFFER, _bufferIndirect); 7920 glBufferData(GL_DRAW_INDIRECT_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW); 7921 7922 glGenBuffers(1, &_ebo); 7923 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ebo); 7924 glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW); 7925 7926 glGenBuffers(1, &_xfb); 7927 glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, _xfb); 7928 glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 4096, &zarro[0], GL_STATIC_DRAW); 7929 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _xfb); 7930 7931 DIResult result; 7932 7933 //Without XFO 7934 glBeginTransformFeedback(GL_POINTS); 7935 7936 glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, NULL); 7937 if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION) 7938 { 7939 result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type"; 7940 } 7941 glDrawArraysIndirect(GL_POINTS, NULL); 7942 if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION) 7943 { 7944 result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type"; 7945 } 7946 glEndTransformFeedback(); 7947 7948 //With XFO 7949 glGenTransformFeedbacks(1, &_xfo); 7950 glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, _xfo); 7951 glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, _xfb); 7952 glBeginTransformFeedback(GL_POINTS); 7953 glPauseTransformFeedback(); 7954 glResumeTransformFeedback(); 7955 7956 glDrawElementsIndirect(GL_POINTS, GL_UNSIGNED_INT, NULL); 7957 if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION) 7958 { 7959 result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type"; 7960 } 7961 glDrawArraysIndirect(GL_POINTS, NULL); 7962 if (!drawWithXFBAllowed && glGetError() != GL_INVALID_OPERATION) 7963 { 7964 result.error() << "Invalid error code returned by a driver for GL_INVALID_OPERATION type"; 7965 } 7966 glEndTransformFeedback(); 7967 7968 glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); 7969 return result.code(); 7970 } 7971 7972 virtual long Cleanup() 7973 { 7974 glDisableVertexAttribArray(0); 7975 glUseProgram(0); 7976 glDeleteProgram(_program); 7977 glDeleteVertexArrays(1, &_vao); 7978 glDeleteBuffers(1, &_buffer); 7979 glDeleteBuffers(1, &_ebo); 7980 glDeleteBuffers(1, &_bufferIndirect); 7981 glDeleteBuffers(1, &_xfb); 7982 glDeleteTransformFeedbacks(1, &_xfo); 7983 return NO_ERROR; 7984 } 7985 7986 std::string Vsh() 7987 { 7988 return api::glslVer() + NL "out highp vec4 dataOut;" NL "in vec4 i_vertex;" NL "void main() {" NL 7989 " dataOut = i_vertex;" NL " gl_Position = i_vertex;" NL "}"; 7990 } 7991 7992private: 7993 GLuint _program; 7994 GLuint _vao, _buffer, _ebo, _bufferIndirect, _xfo, _xfb; 7995}; 7996 7997} // namespace 7998DrawIndirectTestsGL40::DrawIndirectTestsGL40(glcts::Context& context) : TestCaseGroup(context, "draw_indirect", "") 7999{ 8000} 8001 8002DrawIndirectTestsGL40::~DrawIndirectTestsGL40(void) 8003{ 8004} 8005 8006void DrawIndirectTestsGL40::init() 8007{ 8008 using namespace glcts; 8009 8010 DILogger::setOutput(m_context.getTestContext().getLog()); 8011 8012 addChild( 8013 new TestSubcase(m_context, "basic-binding-default", TestSubcase::Create<CDefaultBindingPoint<test_api::GL> >)); 8014 addChild(new TestSubcase(m_context, "basic-binding-zero", TestSubcase::Create<CZeroBindingPoint<test_api::GL> >)); 8015 addChild( 8016 new TestSubcase(m_context, "basic-binding-single", TestSubcase::Create<CSingleBindingPoint<test_api::GL> >)); 8017 addChild(new TestSubcase(m_context, "basic-binding-multi", TestSubcase::Create<CMultiBindingPoint<test_api::GL> >)); 8018 addChild( 8019 new TestSubcase(m_context, "basic-binding-delete", TestSubcase::Create<CDeleteBindingPoint<test_api::GL> >)); 8020 8021 addChild(new TestSubcase(m_context, "basic-buffer-data", TestSubcase::Create<CBufferData<test_api::GL> >)); 8022 addChild(new TestSubcase(m_context, "basic-buffer-subData", TestSubcase::Create<CBufferSubData<test_api::GL> >)); 8023 addChild(new TestSubcase(m_context, "basic-buffer-unMap", TestSubcase::Create<CBufferMap<test_api::GL> >)); 8024 addChild( 8025 new TestSubcase(m_context, "basic-buffer-getPointerv", TestSubcase::Create<CBufferGetPointerv<test_api::GL> >)); 8026 addChild(new TestSubcase(m_context, "basic-buffer-mapRange", TestSubcase::Create<CBufferMapRange<test_api::GL> >)); 8027 addChild(new TestSubcase(m_context, "basic-buffer-flushMappedRange", 8028 TestSubcase::Create<CBufferFlushMappedRange<test_api::GL> >)); 8029 addChild( 8030 new TestSubcase(m_context, "basic-buffer-copySubData", TestSubcase::Create<CBufferCopySubData<test_api::GL> >)); 8031 8032 addChild(new TestSubcase(m_context, "basic-drawArrays-singlePrimitive", 8033 TestSubcase::Create<CVBODrawArraysSingle<test_api::GL> >)); 8034 addChild(new TestSubcase(m_context, "basic-drawArrays-manyPrimitives", 8035 TestSubcase::Create<CVBODrawArraysMany<test_api::GL> >)); 8036 addChild(new TestSubcase(m_context, "basic-drawArrays-instancing", 8037 TestSubcase::Create<CVBODrawArraysInstancing<test_api::GL> >)); 8038 addChild(new TestSubcase(m_context, "basic-drawArrays-xfbPaused", 8039 TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::GL> >)); 8040 addChild(new TestSubcase(m_context, "basic-drawElements-singlePrimitive", 8041 TestSubcase::Create<CVBODrawElementsSingle<test_api::GL> >)); 8042 addChild(new TestSubcase(m_context, "basic-drawElements-manyPrimitives", 8043 TestSubcase::Create<CVBODrawElementsMany<test_api::GL> >)); 8044 addChild(new TestSubcase(m_context, "basic-drawElements-instancing", 8045 TestSubcase::Create<CVBODrawElementsInstancing<test_api::GL> >)); 8046 addChild(new TestSubcase(m_context, "basic-drawElements-xfbPaused", 8047 TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::GL> >)); 8048 8049 addChild(new TestSubcase(m_context, "basic-drawArrays-simple", 8050 TestSubcase::Create<CBufferIndirectDrawArraysSimple<test_api::GL> >)); 8051 addChild(new TestSubcase(m_context, "basic-drawArrays-noFirst", 8052 TestSubcase::Create<CBufferIndirectDrawArraysNoFirst<test_api::GL> >)); 8053 addChild(new TestSubcase(m_context, "basic-drawArrays-bufferOffset", 8054 TestSubcase::Create<CBufferIndirectDrawArraysOffset<test_api::GL> >)); 8055 addChild(new TestSubcase(m_context, "basic-drawArrays-vertexIds", 8056 TestSubcase::Create<CBufferIndirectDrawArraysVertexIds<test_api::GL> >)); 8057 addChild(new TestSubcase(m_context, "basic-drawElements-simple", 8058 TestSubcase::Create<CBufferIndirectDrawElementsSimple<test_api::GL> >)); 8059 addChild(new TestSubcase(m_context, "basic-drawElements-noFirstIndex", 8060 TestSubcase::Create<CBufferIndirectDrawElementsNoFirstIndex<test_api::GL> >)); 8061 addChild(new TestSubcase(m_context, "basic-drawElements-basevertex", 8062 TestSubcase::Create<CBufferIndirectDrawElementsNoBasevertex<test_api::GL> >)); 8063 addChild(new TestSubcase(m_context, "basic-drawElements-bufferOffset", 8064 TestSubcase::Create<CBufferIndirectDrawElementsOffset<test_api::GL> >)); 8065 addChild(new TestSubcase(m_context, "basic-drawElements-vertexIds", 8066 TestSubcase::Create<CBufferIndirectDrawElementsVertexIds<test_api::GL> >)); 8067 8068 addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_short", 8069 TestSubcase::Create<CIndicesDataTypeUnsignedShort<test_api::GL> >)); 8070 addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_byte", 8071 TestSubcase::Create<CIndicesDataTypeUnsignedByte<test_api::GL> >)); 8072 8073 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-points", 8074 TestSubcase::Create<CModeDrawArraysPoints<test_api::GL> >)); 8075 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines", 8076 TestSubcase::Create<CModeDrawArraysLines<test_api::GL> >)); 8077 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip", 8078 TestSubcase::Create<CModeDrawArraysLineStrip<test_api::GL> >)); 8079 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_loop", 8080 TestSubcase::Create<CModeDrawArraysLineLoop<test_api::GL> >)); 8081 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip", 8082 TestSubcase::Create<CModeDrawArraysTriangleStrip<test_api::GL> >)); 8083 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_fan", 8084 TestSubcase::Create<CModeDrawArraysTriangleFan<test_api::GL> >)); 8085 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines_adjacency", 8086 TestSubcase::Create<CModeDrawArraysLinesAdjacency<test_api::GL> >)); 8087 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip_adjacency", 8088 TestSubcase::Create<CModeDrawArraysLineStripAdjacency<test_api::GL> >)); 8089 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangles_adjacency", 8090 TestSubcase::Create<CModeDrawArraysTrianglesAdjacency<test_api::GL> >)); 8091 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip_adjacency", 8092 TestSubcase::Create<CModeDrawArraysTriangleStripAdjacency<test_api::GL> >)); 8093 8094 addChild(new TestSubcase(m_context, "basic-mode-drawElements-points", 8095 TestSubcase::Create<CModeDrawElementsPoints<test_api::GL> >)); 8096 addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines", 8097 TestSubcase::Create<CModeDrawElementsLines<test_api::GL> >)); 8098 addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip", 8099 TestSubcase::Create<CModeDrawElementsLineStrip<test_api::GL> >)); 8100 addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_loop", 8101 TestSubcase::Create<CModeDrawElementsLineLoop<test_api::GL> >)); 8102 addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip", 8103 TestSubcase::Create<CModeDrawElementsTriangleStrip<test_api::GL> >)); 8104 addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_fan", 8105 TestSubcase::Create<CModeDrawElementsTriangleFan<test_api::GL> >)); 8106 addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines_adjacency", 8107 TestSubcase::Create<CModeDrawElementsLinesAdjacency<test_api::GL> >)); 8108 addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip_adjacency", 8109 TestSubcase::Create<CModeDrawElementsLineStripAdjacency<test_api::GL> >)); 8110 addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangles_adjacency", 8111 TestSubcase::Create<CModeDrawElementsTrianglesAdjacency<test_api::GL> >)); 8112 addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip_adjacency", 8113 TestSubcase::Create<CModeDrawElementsTriangleStripAdjacency<test_api::GL> >)); 8114 8115 addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-arrays", 8116 TestSubcase::Create<CTransformFeedbackArray<test_api::GL> >)); 8117 addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-elements", 8118 TestSubcase::Create<CTransformFeedbackElements<test_api::GL> >)); 8119 8120 addChild(new TestSubcase(m_context, "advanced-primitiveRestart-elements", 8121 TestSubcase::Create<CPrimitiveRestartElements<test_api::GL> >)); 8122 8123 addChild(new TestSubcase(m_context, "misc-reservedMustBeZero-arrays", 8124 TestSubcase::Create<CNonZeroReservedMustBeZeroArray<test_api::GL> >)); 8125 addChild(new TestSubcase(m_context, "misc-reservedMustBeZero-elements", 8126 TestSubcase::Create<CNonZeroReservedMustBeZeroElements<test_api::GL> >)); 8127 8128 addChild(new TestSubcase(m_context, "negative-noindirect-arrays", 8129 TestSubcase::Create<CNegativeZeroBufferArray<test_api::GL> >)); 8130 addChild(new TestSubcase(m_context, "negative-noindirect-elements", 8131 TestSubcase::Create<CNegativeZeroBufferElements<test_api::GL> >)); 8132 addChild(new TestSubcase(m_context, "negative-invalidMode-arrays", 8133 TestSubcase::Create<CNegativeInvalidModeArray<test_api::GL> >)); 8134 addChild(new TestSubcase(m_context, "negative-invalidMode-elements", 8135 TestSubcase::Create<CNegativeInvalidModeElements<test_api::GL> >)); 8136 addChild( 8137 new TestSubcase(m_context, "negative-noVAO-arrays", TestSubcase::Create<CNegativeNoVAOArrays<test_api::GL> >)); 8138 addChild(new TestSubcase(m_context, "negative-noVAO-elements", 8139 TestSubcase::Create<CNegativeNoVAOElements<test_api::GL> >)); 8140 addChild(new TestSubcase(m_context, "negative-bufferMapped-arrays", 8141 TestSubcase::Create<CNegativeBufferMappedArray<test_api::GL> >)); 8142 addChild(new TestSubcase(m_context, "negative-bufferMapped-elements", 8143 TestSubcase::Create<CNegativeBufferMappedElements<test_api::GL> >)); 8144 addChild(new TestSubcase(m_context, "negative-invalidType-elements", 8145 TestSubcase::Create<CNegativeDataWrongElements<test_api::GL> >)); 8146 addChild(new TestSubcase(m_context, "negative-gshIncompatible-arrays", 8147 TestSubcase::Create<CNegativeGshArray<test_api::GL> >)); 8148 addChild(new TestSubcase(m_context, "negative-gshIncompatible-elements", 8149 TestSubcase::Create<CNegativeGshElements<test_api::GL> >)); 8150 addChild(new TestSubcase(m_context, "negative-wrongOffset-arrays", 8151 TestSubcase::Create<CNegativeStructureWrongOffsetArray<test_api::GL> >)); 8152 addChild(new TestSubcase(m_context, "negative-wrongOffset-elements", 8153 TestSubcase::Create<CNegativeStructureWrongOffsetElements<test_api::GL> >)); 8154 addChild(new TestSubcase(m_context, "negative-invalidSize-arrays", 8155 TestSubcase::Create<CNegativeInvalidSizeArrays<test_api::GL> >)); 8156 addChild(new TestSubcase(m_context, "negative-invalidSize-elements", 8157 TestSubcase::Create<CNegativeInvalidSizeElements<test_api::GL> >)); 8158 addChild(new TestSubcase(m_context, "negative-unalignedOffset", 8159 TestSubcase::Create<CNegativeUnalignedOffset<test_api::GL> >)); 8160} 8161 8162DrawIndirectTestsGL43::DrawIndirectTestsGL43(glcts::Context& context) : TestCaseGroup(context, "draw_indirect_43", "") 8163{ 8164} 8165 8166DrawIndirectTestsGL43::~DrawIndirectTestsGL43(void) 8167{ 8168} 8169 8170void DrawIndirectTestsGL43::init() 8171{ 8172 using namespace glcts; 8173 8174 DILogger::setOutput(m_context.getTestContext().getLog()); 8175 addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-arrays", 8176 TestSubcase::Create<CComputeShaderArray<test_api::GL> >)); 8177 addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-elements", 8178 TestSubcase::Create<CComputeShaderElements<test_api::GL> >)); 8179} 8180 8181DrawIndirectTestsES31::DrawIndirectTestsES31(glcts::Context& context) : TestCaseGroup(context, "draw_indirect", "") 8182{ 8183} 8184 8185DrawIndirectTestsES31::~DrawIndirectTestsES31(void) 8186{ 8187} 8188 8189void DrawIndirectTestsES31::init() 8190{ 8191 using namespace glcts; 8192 8193 DILogger::setOutput(m_context.getTestContext().getLog()); 8194 8195 addChild( 8196 new TestSubcase(m_context, "basic-binding-default", TestSubcase::Create<CDefaultBindingPoint<test_api::ES3> >)); 8197 addChild(new TestSubcase(m_context, "basic-binding-zero", TestSubcase::Create<CZeroBindingPoint<test_api::ES3> >)); 8198 addChild( 8199 new TestSubcase(m_context, "basic-binding-single", TestSubcase::Create<CSingleBindingPoint<test_api::ES3> >)); 8200 addChild( 8201 new TestSubcase(m_context, "basic-binding-multi", TestSubcase::Create<CMultiBindingPoint<test_api::ES3> >)); 8202 addChild( 8203 new TestSubcase(m_context, "basic-binding-delete", TestSubcase::Create<CDeleteBindingPoint<test_api::ES3> >)); 8204 8205 addChild(new TestSubcase(m_context, "basic-buffer-data", TestSubcase::Create<CBufferData<test_api::ES3> >)); 8206 addChild(new TestSubcase(m_context, "basic-buffer-subData", TestSubcase::Create<CBufferSubData<test_api::ES3> >)); 8207 addChild(new TestSubcase(m_context, "basic-buffer-getPointerv", 8208 TestSubcase::Create<CBufferGetPointerv<test_api::ES3> >)); 8209 addChild(new TestSubcase(m_context, "basic-buffer-mapRange", TestSubcase::Create<CBufferMapRange<test_api::ES3> >)); 8210 addChild(new TestSubcase(m_context, "basic-buffer-flushMappedRange", 8211 TestSubcase::Create<CBufferFlushMappedRange<test_api::ES3> >)); 8212 addChild(new TestSubcase(m_context, "basic-buffer-copySubData", 8213 TestSubcase::Create<CBufferCopySubData<test_api::ES3> >)); 8214 8215 addChild(new TestSubcase(m_context, "basic-drawArrays-singlePrimitive", 8216 TestSubcase::Create<CVBODrawArraysSingle<test_api::ES3> >)); 8217 addChild(new TestSubcase(m_context, "basic-drawArrays-manyPrimitives", 8218 TestSubcase::Create<CVBODrawArraysMany<test_api::ES3> >)); 8219 addChild(new TestSubcase(m_context, "basic-drawArrays-instancing", 8220 TestSubcase::Create<CVBODrawArraysInstancing<test_api::ES3> >)); 8221 addChild(new TestSubcase(m_context, "basic-drawArrays-xfbPaused", 8222 TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::ES3> >)); 8223 addChild(new TestSubcase(m_context, "basic-drawElements-singlePrimitive", 8224 TestSubcase::Create<CVBODrawElementsSingle<test_api::ES3> >)); 8225 addChild(new TestSubcase(m_context, "basic-drawElements-manyPrimitives", 8226 TestSubcase::Create<CVBODrawElementsMany<test_api::ES3> >)); 8227 addChild(new TestSubcase(m_context, "basic-drawElements-instancing", 8228 TestSubcase::Create<CVBODrawElementsInstancing<test_api::ES3> >)); 8229 addChild(new TestSubcase(m_context, "basic-drawElements-xfbPaused", 8230 TestSubcase::Create<CVBODrawArraysXFBPaused<test_api::ES3> >)); 8231 8232 addChild(new TestSubcase(m_context, "basic-drawArrays-simple", 8233 TestSubcase::Create<CBufferIndirectDrawArraysSimple<test_api::ES3> >)); 8234 addChild(new TestSubcase(m_context, "basic-drawArrays-noFirst", 8235 TestSubcase::Create<CBufferIndirectDrawArraysNoFirst<test_api::ES3> >)); 8236 addChild(new TestSubcase(m_context, "basic-drawArrays-bufferOffset", 8237 TestSubcase::Create<CBufferIndirectDrawArraysOffset<test_api::ES3> >)); 8238 addChild(new TestSubcase(m_context, "basic-drawArrays-vertexIds", 8239 TestSubcase::Create<CBufferIndirectDrawArraysVertexIds<test_api::ES3> >)); 8240 addChild(new TestSubcase(m_context, "basic-drawElements-simple", 8241 TestSubcase::Create<CBufferIndirectDrawElementsSimple<test_api::ES3> >)); 8242 addChild(new TestSubcase(m_context, "basic-drawElements-noFirstIndex", 8243 TestSubcase::Create<CBufferIndirectDrawElementsNoFirstIndex<test_api::ES3> >)); 8244 addChild(new TestSubcase(m_context, "basic-drawElements-basevertex", 8245 TestSubcase::Create<CBufferIndirectDrawElementsNoBasevertex<test_api::ES3> >)); 8246 addChild(new TestSubcase(m_context, "basic-drawElements-bufferOffset", 8247 TestSubcase::Create<CBufferIndirectDrawElementsOffset<test_api::ES3> >)); 8248 addChild(new TestSubcase(m_context, "basic-drawElements-vertexIds", 8249 TestSubcase::Create<CBufferIndirectDrawElementsVertexIds<test_api::ES3> >)); 8250 8251 addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_short", 8252 TestSubcase::Create<CIndicesDataTypeUnsignedShort<test_api::ES3> >)); 8253 addChild(new TestSubcase(m_context, "basic-indicesDataType-unsigned_byte", 8254 TestSubcase::Create<CIndicesDataTypeUnsignedByte<test_api::ES3> >)); 8255 8256 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-points", 8257 TestSubcase::Create<CModeDrawArraysPoints<test_api::ES3> >)); 8258 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines", 8259 TestSubcase::Create<CModeDrawArraysLines<test_api::ES3> >)); 8260 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip", 8261 TestSubcase::Create<CModeDrawArraysLineStrip<test_api::ES3> >)); 8262 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_loop", 8263 TestSubcase::Create<CModeDrawArraysLineLoop<test_api::ES3> >)); 8264 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip", 8265 TestSubcase::Create<CModeDrawArraysTriangleStrip<test_api::ES3> >)); 8266 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_fan", 8267 TestSubcase::Create<CModeDrawArraysTriangleFan<test_api::ES3> >)); 8268 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-lines_adjacency", 8269 TestSubcase::Create<CModeDrawArraysLinesAdjacency<test_api::ES3> >)); 8270 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-line_strip_adjacency", 8271 TestSubcase::Create<CModeDrawArraysLineStripAdjacency<test_api::ES3> >)); 8272 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangles_adjacency", 8273 TestSubcase::Create<CModeDrawArraysTrianglesAdjacency<test_api::ES3> >)); 8274 addChild(new TestSubcase(m_context, "basic-mode-drawArrays-triangle_strip_adjacency", 8275 TestSubcase::Create<CModeDrawArraysTriangleStripAdjacency<test_api::ES3> >)); 8276 8277 addChild(new TestSubcase(m_context, "basic-mode-drawElements-points", 8278 TestSubcase::Create<CModeDrawElementsPoints<test_api::ES3> >)); 8279 addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines", 8280 TestSubcase::Create<CModeDrawElementsLines<test_api::ES3> >)); 8281 addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip", 8282 TestSubcase::Create<CModeDrawElementsLineStrip<test_api::ES3> >)); 8283 addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_loop", 8284 TestSubcase::Create<CModeDrawElementsLineLoop<test_api::ES3> >)); 8285 addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip", 8286 TestSubcase::Create<CModeDrawElementsTriangleStrip<test_api::ES3> >)); 8287 addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_fan", 8288 TestSubcase::Create<CModeDrawElementsTriangleFan<test_api::ES3> >)); 8289 addChild(new TestSubcase(m_context, "basic-mode-drawElements-lines_adjacency", 8290 TestSubcase::Create<CModeDrawElementsLinesAdjacency<test_api::ES3> >)); 8291 addChild(new TestSubcase(m_context, "basic-mode-drawElements-line_strip_adjacency", 8292 TestSubcase::Create<CModeDrawElementsLineStripAdjacency<test_api::ES3> >)); 8293 addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangles_adjacency", 8294 TestSubcase::Create<CModeDrawElementsTrianglesAdjacency<test_api::ES3> >)); 8295 addChild(new TestSubcase(m_context, "basic-mode-drawElements-triangle_strip_adjacency", 8296 TestSubcase::Create<CModeDrawElementsTriangleStripAdjacency<test_api::ES3> >)); 8297 8298 addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-arrays", 8299 TestSubcase::Create<CTransformFeedbackArray<test_api::ES3> >)); 8300 addChild(new TestSubcase(m_context, "advanced-twoPass-transformFeedback-elements", 8301 TestSubcase::Create<CTransformFeedbackElements<test_api::ES3> >)); 8302 8303 addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-arrays", 8304 TestSubcase::Create<CComputeShaderArray<test_api::ES3> >)); 8305 addChild(new TestSubcase(m_context, "advanced-twoPass-Compute-elements", 8306 TestSubcase::Create<CComputeShaderElements<test_api::ES3> >)); 8307 8308 addChild(new TestSubcase(m_context, "advanced-primitiveRestart-elements", 8309 TestSubcase::Create<CPrimitiveRestartElements<test_api::ES3> >)); 8310 8311 addChild(new TestSubcase(m_context, "misc-reservedMustBeZero-arrays", 8312 TestSubcase::Create<CNonZeroReservedMustBeZeroArray<test_api::ES3> >)); 8313 addChild(new TestSubcase(m_context, "misc-reservedMustBeZero-elements", 8314 TestSubcase::Create<CNonZeroReservedMustBeZeroElements<test_api::ES3> >)); 8315 8316 addChild(new TestSubcase(m_context, "negative-noindirect-arrays", 8317 TestSubcase::Create<CNegativeZeroBufferArray<test_api::ES3> >)); 8318 addChild(new TestSubcase(m_context, "negative-noindirect-elements", 8319 TestSubcase::Create<CNegativeZeroBufferElements<test_api::ES3> >)); 8320 addChild(new TestSubcase(m_context, "negative-invalidMode-arrays", 8321 TestSubcase::Create<CNegativeInvalidModeArray<test_api::ES3> >)); 8322 addChild(new TestSubcase(m_context, "negative-invalidMode-elements", 8323 TestSubcase::Create<CNegativeInvalidModeElements<test_api::ES3> >)); 8324 addChild( 8325 new TestSubcase(m_context, "negative-noVAO-arrays", TestSubcase::Create<CNegativeNoVAOArrays<test_api::ES3> >)); 8326 addChild(new TestSubcase(m_context, "negative-noVAO-elements", 8327 TestSubcase::Create<CNegativeNoVAOElements<test_api::ES3> >)); 8328 addChild( 8329 new TestSubcase(m_context, "negative-noVBO-arrays", TestSubcase::Create<CNegativeNoVBOArrays<test_api::ES3> >)); 8330 addChild(new TestSubcase(m_context, "negative-noVBO-elements", 8331 TestSubcase::Create<CNegativeNoVBOElements<test_api::ES3> >)); 8332 addChild(new TestSubcase(m_context, "negative-bufferMapped-arrays", 8333 TestSubcase::Create<CNegativeBufferMappedArray<test_api::ES3> >)); 8334 addChild(new TestSubcase(m_context, "negative-bufferMapped-elements", 8335 TestSubcase::Create<CNegativeBufferMappedElements<test_api::ES3> >)); 8336 addChild(new TestSubcase(m_context, "negative-invalidType-elements", 8337 TestSubcase::Create<CNegativeDataWrongElements<test_api::ES3> >)); 8338 8339 addChild(new TestSubcase(m_context, "negative-wrongOffset-arrays", 8340 TestSubcase::Create<CNegativeStructureWrongOffsetArray<test_api::ES3> >)); 8341 addChild(new TestSubcase(m_context, "negative-wrongOffset-elements", 8342 TestSubcase::Create<CNegativeStructureWrongOffsetElements<test_api::ES3> >)); 8343 addChild(new TestSubcase(m_context, "negative-invalidSize-arrays", 8344 TestSubcase::Create<CNegativeInvalidSizeArrays<test_api::ES3> >)); 8345 addChild(new TestSubcase(m_context, "negative-invalidSize-elements", 8346 TestSubcase::Create<CNegativeInvalidSizeElements<test_api::ES3> >)); 8347 addChild(new TestSubcase(m_context, "negative-unalignedOffset", 8348 TestSubcase::Create<CNegativeUnalignedOffset<test_api::ES3> >)); 8349 addChild(new TestSubcase(m_context, "negative-xfb", TestSubcase::Create<CNegativeXFB<test_api::ES3> >)); 8350} 8351} 8352