es31fDrawElementsBaseVertexTests.cpp revision 3c865084eb27036bf9fd43a41a7eae277a6ee170
1/*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.1 Module 3 * ------------------------------------------------- 4 * 5 * Copyright 2017 The Android Open Source Project 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 GL_EXT_draw_elements_base_vertex tests. 22 *//*--------------------------------------------------------------------*/ 23 24#include "es31fDrawElementsBaseVertexTests.hpp" 25#include "deRandom.hpp" 26#include "deStringUtil.hpp" 27#include "tcuRenderTarget.hpp" 28#include "tcuVectorUtil.hpp" 29#include "sglrGLContext.hpp" 30#include "glsDrawTest.hpp" 31#include "gluStrUtil.hpp" 32#include "gluPixelTransfer.hpp" 33#include "gluContextInfo.hpp" 34 35#include "glwEnums.hpp" 36#include "glwFunctions.hpp" 37 38#include <string> 39#include <set> 40 41using std::vector; 42using std::string; 43using tcu::TestLog; 44 45using namespace glw; 46 47namespace deqp 48{ 49namespace gles31 50{ 51namespace Functional 52{ 53namespace 54{ 55 56enum TestIterationType 57{ 58 TYPE_DRAW_COUNT, // !< test with 1, 5, and 25 primitives 59 TYPE_INSTANCE_COUNT, // !< test with 1, 4, and 11 instances 60 61 TYPE_LAST 62}; 63 64static size_t getElementCount (gls::DrawTestSpec::Primitive primitive, size_t primitiveCount) 65{ 66 switch (primitive) 67 { 68 case gls::DrawTestSpec::PRIMITIVE_POINTS: return primitiveCount; 69 case gls::DrawTestSpec::PRIMITIVE_TRIANGLES: return primitiveCount * 3; 70 case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN: return primitiveCount + 2; 71 case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP: return primitiveCount + 2; 72 case gls::DrawTestSpec::PRIMITIVE_LINES: return primitiveCount * 2; 73 case gls::DrawTestSpec::PRIMITIVE_LINE_STRIP: return primitiveCount + 1; 74 case gls::DrawTestSpec::PRIMITIVE_LINE_LOOP: return (primitiveCount==1) ? (2) : (primitiveCount); 75 case gls::DrawTestSpec::PRIMITIVE_LINES_ADJACENCY: return primitiveCount * 4; 76 case gls::DrawTestSpec::PRIMITIVE_LINE_STRIP_ADJACENCY: return primitiveCount + 3; 77 case gls::DrawTestSpec::PRIMITIVE_TRIANGLES_ADJACENCY: return primitiveCount * 6; 78 case gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP_ADJACENCY: return primitiveCount * 2 + 4; 79 default: 80 DE_ASSERT(false); 81 return 0; 82 } 83} 84 85static void addRangeElementsToSpec (gls::DrawTestSpec& spec) 86{ 87 if (spec.drawMethod == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX) 88 { 89 spec.indexMin = 0; 90 spec.indexMax = (int)getElementCount(spec.primitive, spec.primitiveCount); 91 } 92} 93 94static void addTestIterations (gls::DrawTest* test, gls::DrawTestSpec& spec, TestIterationType type) 95{ 96 if (type == TYPE_DRAW_COUNT) 97 { 98 spec.primitiveCount = 1; 99 addRangeElementsToSpec(spec); 100 test->addIteration(spec, "draw count = 1"); 101 102 spec.primitiveCount = 5; 103 addRangeElementsToSpec(spec); 104 test->addIteration(spec, "draw count = 5"); 105 106 spec.primitiveCount = 25; 107 addRangeElementsToSpec(spec); 108 test->addIteration(spec, "draw count = 25"); 109 } 110 else if (type == TYPE_INSTANCE_COUNT) 111 { 112 spec.instanceCount = 1; 113 addRangeElementsToSpec(spec); 114 test->addIteration(spec, "instance count = 1"); 115 116 spec.instanceCount = 4; 117 addRangeElementsToSpec(spec); 118 test->addIteration(spec, "instance count = 4"); 119 120 spec.instanceCount = 11; 121 addRangeElementsToSpec(spec); 122 test->addIteration(spec, "instance count = 11"); 123 } 124 else 125 DE_ASSERT(false); 126} 127 128static void genBasicSpec (gls::DrawTestSpec& spec, gls::DrawTestSpec::DrawMethod method) 129{ 130 spec.apiType = glu::ApiType::es(3,1); 131 spec.primitive = gls::DrawTestSpec::PRIMITIVE_TRIANGLES; 132 spec.primitiveCount = 5; 133 spec.drawMethod = method; 134 spec.indexType = gls::DrawTestSpec::INDEXTYPE_LAST; 135 spec.indexPointerOffset = 0; 136 spec.indexStorage = gls::DrawTestSpec::STORAGE_LAST; 137 spec.first = 0; 138 spec.indexMin = 0; 139 spec.indexMax = 0; 140 spec.instanceCount = 1; 141 spec.indirectOffset = 0; 142 143 spec.attribs.resize(2); 144 145 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT; 146 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2; 147 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER; 148 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW; 149 spec.attribs[0].componentCount = 4; 150 spec.attribs[0].offset = 0; 151 spec.attribs[0].stride = 0; 152 spec.attribs[0].normalize = false; 153 spec.attribs[0].instanceDivisor = 0; 154 spec.attribs[0].useDefaultAttribute = false; 155 156 spec.attribs[1].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT; 157 spec.attribs[1].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2; 158 spec.attribs[1].storage = gls::DrawTestSpec::STORAGE_BUFFER; 159 spec.attribs[1].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW; 160 spec.attribs[1].componentCount = 2; 161 spec.attribs[1].offset = 0; 162 spec.attribs[1].stride = 0; 163 spec.attribs[1].normalize = false; 164 spec.attribs[1].instanceDivisor = 0; 165 spec.attribs[1].useDefaultAttribute = false; 166 167 addRangeElementsToSpec(spec); 168} 169 170class VertexIDCase : public TestCase 171{ 172public: 173 VertexIDCase (Context& context, gls::DrawTestSpec::DrawMethod drawMethod); 174 ~VertexIDCase (void); 175 176 void init (void); 177 void deinit (void); 178 IterateResult iterate (void); 179 180 void draw (GLenum mode, GLsizei count, GLenum type, GLvoid* indices, GLint baseVertex); 181 void verifyImage (const tcu::Surface& image); 182 183private: 184 const glw::Functions& m_gl; 185 glu::ShaderProgram* m_program; 186 GLuint m_coordinatesBuffer; 187 GLuint m_elementsBuffer; 188 int m_iterNdx; 189 gls::DrawTestSpec::DrawMethod m_method; 190 191 enum 192 { 193 VIEWPORT_WIDTH = 64, 194 VIEWPORT_HEIGHT = 64 195 }; 196 197 enum 198 { 199 MAX_VERTICES = 2*3 //!< 2 triangles, totals 6 vertices 200 }; 201}; 202 203VertexIDCase::VertexIDCase (Context& context, gls::DrawTestSpec::DrawMethod drawMethod) 204 : TestCase (context, "vertex_id", "gl_VertexID Test") 205 , m_gl (m_context.getRenderContext().getFunctions()) 206 , m_program (DE_NULL) 207 , m_coordinatesBuffer (0) 208 , m_elementsBuffer (0) 209 , m_iterNdx (0) 210 , m_method (drawMethod) 211{ 212} 213 214VertexIDCase::~VertexIDCase (void) 215{ 216 VertexIDCase::deinit(); 217} 218 219void VertexIDCase::init (void) 220{ 221 m_testCtx.getLog() << TestLog::Message 222 << "gl_VertexID should be the index of the vertex that is being passed to the shader. i.e. indices[i] + basevertex" 223 << TestLog::EndMessage; 224 225 DE_ASSERT(!m_program); 226 m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources( 227 "#version 310 es\n" 228 "in highp vec4 a_position;\n" 229 "out mediump vec4 v_color;\n" 230 "uniform highp vec4 u_colors[8];\n" 231 "void main (void)\n" 232 "{\n" 233 " gl_Position = a_position;\n" 234 " v_color = u_colors[gl_VertexID];\n" 235 "}\n", 236 237 "#version 310 es\n" 238 "in mediump vec4 v_color;\n" 239 "layout(location = 0) out mediump vec4 o_color;\n" 240 "void main (void)\n" 241 "{\n" 242 " o_color = v_color;\n" 243 "}\n")); 244 245 m_testCtx.getLog() << *m_program; 246 247 if (!m_program->isOk()) 248 { 249 delete m_program; 250 m_program = DE_NULL; 251 TCU_FAIL("Failed to compile shader program"); 252 } 253 254 GLU_CHECK_GLW_CALL(m_gl, useProgram(m_program->getProgram())); 255 256 GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer)); 257 GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_elementsBuffer)); 258} 259 260void VertexIDCase::deinit (void) 261{ 262 delete m_program; 263 m_program = DE_NULL; 264 265 if (m_elementsBuffer) 266 { 267 GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_elementsBuffer)); 268 m_elementsBuffer = 0; 269 } 270 271 if (m_coordinatesBuffer) 272 { 273 GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer)); 274 m_coordinatesBuffer = 0; 275 } 276} 277 278void VertexIDCase::draw (GLenum mode, GLsizei count, GLenum type, GLvoid* indices, GLint baseVertex) 279{ 280 switch (m_method) 281 { 282 case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX: 283 GLU_CHECK_GLW_CALL(m_gl, drawElementsBaseVertex(mode, count, type, indices, baseVertex)); 284 break; 285 286 case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX: 287 { 288 GLint maxElementsVertices = 0; 289 GLU_CHECK_GLW_CALL(m_gl, getIntegerv(GL_MAX_ELEMENTS_VERTICES, &maxElementsVertices)); 290 GLU_CHECK_GLW_CALL(m_gl, drawRangeElementsBaseVertex(mode, 0, maxElementsVertices, count, type, indices, baseVertex)); 291 break; 292 } 293 294 case gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX: 295 GLU_CHECK_GLW_CALL(m_gl, drawElementsInstancedBaseVertex(mode, count, type, indices, 1, baseVertex)); 296 break; 297 298 default: 299 DE_FATAL("Draw method not supported"); 300 } 301} 302 303void VertexIDCase::verifyImage (const tcu::Surface& image) 304{ 305 tcu::TestLog& log = m_testCtx.getLog(); 306 bool isOk = true; 307 308 const int colorThreshold = 0; // expect perfect match 309 tcu::Surface error (image.getWidth(), image.getHeight()); 310 311 for (int y = 0; y < image.getHeight(); y++) 312 for (int x = 0; x < image.getWidth(); x++) 313 { 314 const tcu::RGBA pixel = image.getPixel(x, y); 315 bool pixelOk = true; 316 317 // Ignore pixels not drawn with basevertex 318 if ((x < image.getWidth()* 1/4) || (x > image.getWidth() * 3/4) 319 || (y < image.getHeight() * 1/4) || (y > image.getHeight() * 3/4)) 320 continue; 321 322 // Any pixel with !(B ~= 255) is faulty 323 if (de::abs(pixel.getBlue() - 255) > colorThreshold) 324 pixelOk = false; 325 326 error.setPixel(x, y, (pixelOk) ? (tcu::RGBA(0, 255, 0, 255)) : (tcu::RGBA(255, 0, 0, 255))); 327 isOk = isOk && pixelOk; 328 } 329 330 if (!isOk) 331 { 332 log << TestLog::Message << "Image verification failed." << TestLog::EndMessage; 333 log << TestLog::ImageSet("Verification result", "Result of rendering") 334 << TestLog::Image("Result", "Result", image) 335 << TestLog::Image("Error Mask", "Error mask", error) 336 << TestLog::EndImageSet; 337 } 338 else 339 { 340 log << TestLog::ImageSet("Verification result", "Result of rendering") 341 << TestLog::Image("Result", "Result", image) 342 << TestLog::EndImageSet; 343 } 344 345 if (isOk) 346 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 347 else 348 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result image invalid"); 349} 350 351VertexIDCase::IterateResult VertexIDCase::iterate (void) 352{ 353 const GLuint drawCount = 6; 354 const GLuint baseVertex = 4; 355 const GLuint coordLocation = m_gl.getAttribLocation(m_program->getProgram(), "a_position"); 356 const GLuint colorLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_colors[0]"); 357 358 tcu::Surface surface(VIEWPORT_WIDTH, VIEWPORT_HEIGHT); 359 360 const GLfloat coords[] = 361 { 362 // full viewport quad 363 -1.0f, -1.0f, 364 +1.0f, -1.0f, 365 +1.0f, +1.0f, 366 -1.0f, +1.0f, 367 368 // half viewport quad centred 369 -0.5f, -0.5f, 370 +0.5f, -0.5f, 371 +0.5f, +0.5f, 372 -0.5f, +0.5f, 373 }; 374 375 const GLushort indices[] = 376 { 377 0, 1, 2, 2, 3, 0, 378 }; 379 380 const GLfloat colors[] = 381 { 382 0.0f, 0.0f, 0.0f, 1.0f, 383 0.5f, 1.0f, 0.5f, 1.0f, 384 0.0f, 0.5f, 1.0f, 1.0f, 385 0.0f, 1.0f, 0.0f, 1.0f, 386 387 0.0f, 0.0f, 1.0f, 1.0f, // blue 388 0.0f, 0.0f, 1.0f, 1.0f, // blue 389 0.0f, 0.0f, 1.0f, 1.0f, // blue 390 0.0f, 0.0f, 1.0f, 1.0f, // blue 391 }; 392 393 GLU_CHECK_GLW_CALL(m_gl, viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT)); 394 GLU_CHECK_GLW_CALL(m_gl, clearColor(1.0f, 1.0f, 1.0f, 1.0f)); // white 395 GLU_CHECK_GLW_CALL(m_gl, clear(GL_COLOR_BUFFER_BIT)); 396 397 GLU_CHECK_GLW_CALL(m_gl, uniform4fv(colorLocation, DE_LENGTH_OF_ARRAY(colors), &colors[0])); 398 399 GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer)); 400 GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW)); 401 GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(coordLocation)); 402 GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL)); 403 404 if (m_iterNdx == 0) 405 { 406 tcu::ScopedLogSection logSection (m_testCtx.getLog(), "Iter0", "Indices in client-side array"); 407 draw(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, (GLvoid*)indices, baseVertex); 408 } 409 410 if (m_iterNdx == 1) 411 { 412 tcu::ScopedLogSection logSection (m_testCtx.getLog(), "Iter1", "Indices in element array buffer"); 413 GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementsBuffer)); 414 GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0], GL_STATIC_DRAW)); 415 draw(GL_TRIANGLES, drawCount, GL_UNSIGNED_SHORT, DE_NULL, baseVertex); 416 } 417 418 glu::readPixels(m_context.getRenderContext(), 0, 0, surface.getAccess()); 419 verifyImage(surface); 420 421 m_iterNdx += 1; 422 423 return (m_iterNdx < 2) ? CONTINUE : STOP; 424} 425 426class BuiltInVariableGroup : public TestCaseGroup 427{ 428public: 429 BuiltInVariableGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod); 430 ~BuiltInVariableGroup (void); 431 432 void init (void); 433 434private: 435 gls::DrawTestSpec::DrawMethod m_method; 436}; 437 438BuiltInVariableGroup::BuiltInVariableGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod) 439 : TestCaseGroup (context, name, descr) 440 , m_method (drawMethod) 441{ 442} 443 444BuiltInVariableGroup::~BuiltInVariableGroup (void) 445{ 446} 447 448void BuiltInVariableGroup::init (void) 449{ 450 addChild(new VertexIDCase(m_context, m_method)); 451} 452 453class IndexGroup : public TestCaseGroup 454{ 455public: 456 IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod); 457 ~IndexGroup (void); 458 459 void init (void); 460 461private: 462 gls::DrawTestSpec::DrawMethod m_method; 463}; 464 465IndexGroup::IndexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod) 466 : TestCaseGroup (context, name, descr) 467 , m_method (drawMethod) 468{ 469} 470 471IndexGroup::~IndexGroup (void) 472{ 473} 474 475void IndexGroup::init (void) 476{ 477 struct IndexTest 478 { 479 gls::DrawTestSpec::IndexType type; 480 int offsets[3]; 481 }; 482 483 const IndexTest tests[] = 484 { 485 { gls::DrawTestSpec::INDEXTYPE_BYTE, { 0, 1, -1 } }, 486 { gls::DrawTestSpec::INDEXTYPE_SHORT, { 0, 2, -1 } }, 487 { gls::DrawTestSpec::INDEXTYPE_INT, { 0, 4, -1 } }, 488 }; 489 490 gls::DrawTestSpec spec; 491 genBasicSpec(spec, m_method); 492 493 spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER; 494 495 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx) 496 { 497 const IndexTest& indexTest = tests[testNdx]; 498 499 const std::string name = std::string("index_") + gls::DrawTestSpec::indexTypeToString(indexTest.type); 500 const std::string desc = std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type); 501 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str()); 502 503 spec.indexType = indexTest.type; 504 505 for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.offsets) && indexTest.offsets[iterationNdx] != -1; ++iterationNdx) 506 { 507 const std::string iterationDesc = std::string("first vertex ") + de::toString(indexTest.offsets[iterationNdx] / gls::DrawTestSpec::indexTypeSize(indexTest.type)); 508 spec.indexPointerOffset = indexTest.offsets[iterationNdx]; 509 test->addIteration(spec, iterationDesc.c_str()); 510 } 511 512 addChild(test); 513 } 514} 515 516class BaseVertexGroup : public TestCaseGroup 517{ 518public: 519 BaseVertexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod); 520 ~BaseVertexGroup (void); 521 522 void init (void); 523 524private: 525 gls::DrawTestSpec::DrawMethod m_method; 526}; 527 528BaseVertexGroup::BaseVertexGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod) 529 : TestCaseGroup (context, name, descr) 530 , m_method (drawMethod) 531{ 532} 533 534BaseVertexGroup::~BaseVertexGroup (void) 535{ 536} 537 538void BaseVertexGroup::init (void) 539{ 540 struct IndexTest 541 { 542 bool positiveBase; 543 gls::DrawTestSpec::IndexType type; 544 int baseVertex[2]; 545 }; 546 547 const IndexTest tests[] = 548 { 549 { true, gls::DrawTestSpec::INDEXTYPE_BYTE, { 1, 2 } }, 550 { true, gls::DrawTestSpec::INDEXTYPE_SHORT, { 1, 2 } }, 551 { true, gls::DrawTestSpec::INDEXTYPE_INT, { 1, 2 } }, 552 { false, gls::DrawTestSpec::INDEXTYPE_BYTE, { -1, -2 } }, 553 { false, gls::DrawTestSpec::INDEXTYPE_SHORT, { -1, -2 } }, 554 { false, gls::DrawTestSpec::INDEXTYPE_INT, { -1, -2 } }, 555 }; 556 557 gls::DrawTestSpec spec; 558 genBasicSpec(spec, m_method); 559 560 spec.indexStorage = gls::DrawTestSpec::STORAGE_BUFFER; 561 562 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(tests); ++testNdx) 563 { 564 const IndexTest& indexTest = tests[testNdx]; 565 566 const std::string name = std::string("index_") + (indexTest.positiveBase ? "" : "neg_") + gls::DrawTestSpec::indexTypeToString(indexTest.type); 567 const std::string desc = std::string("index ") + gls::DrawTestSpec::indexTypeToString(indexTest.type); 568 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), name.c_str(), desc.c_str()); 569 570 spec.indexType = indexTest.type; 571 572 for (int iterationNdx = 0; iterationNdx < DE_LENGTH_OF_ARRAY(indexTest.baseVertex); ++iterationNdx) 573 { 574 const std::string iterationDesc = std::string("base vertex ") + de::toString(indexTest.baseVertex[iterationNdx]); 575 spec.baseVertex = indexTest.baseVertex[iterationNdx]; 576 test->addIteration(spec, iterationDesc.c_str()); 577 } 578 579 addChild(test); 580 } 581} 582 583class AttributeGroup : public TestCaseGroup 584{ 585public: 586 AttributeGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage); 587 ~AttributeGroup (void); 588 589 void init (void); 590 591private: 592 gls::DrawTestSpec::DrawMethod m_method; 593 gls::DrawTestSpec::Primitive m_primitive; 594 gls::DrawTestSpec::IndexType m_indexType; 595 gls::DrawTestSpec::Storage m_indexStorage; 596}; 597 598AttributeGroup::AttributeGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod, gls::DrawTestSpec::Primitive primitive, gls::DrawTestSpec::IndexType indexType, gls::DrawTestSpec::Storage indexStorage) 599 : TestCaseGroup (context, name, descr) 600 , m_method (drawMethod) 601 , m_primitive (primitive) 602 , m_indexType (indexType) 603 , m_indexStorage (indexStorage) 604{ 605} 606 607AttributeGroup::~AttributeGroup (void) 608{ 609} 610 611void AttributeGroup::init (void) 612{ 613 // Single attribute 614 { 615 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "single_attribute", "Single attribute array."); 616 gls::DrawTestSpec spec; 617 618 spec.apiType = glu::ApiType::es(3,1); 619 spec.primitive = m_primitive; 620 spec.primitiveCount = 5; 621 spec.drawMethod = m_method; 622 spec.indexType = m_indexType; 623 spec.indexPointerOffset = 0; 624 spec.indexStorage = m_indexStorage; 625 spec.first = 0; 626 spec.indexMin = 0; 627 spec.indexMax = 0; 628 spec.instanceCount = 1; 629 spec.indirectOffset = 0; 630 631 spec.attribs.resize(1); 632 633 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT; 634 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2; 635 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER; 636 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW; 637 spec.attribs[0].componentCount = 2; 638 spec.attribs[0].offset = 0; 639 spec.attribs[0].stride = 0; 640 spec.attribs[0].normalize = false; 641 spec.attribs[0].instanceDivisor = 0; 642 spec.attribs[0].useDefaultAttribute = false; 643 644 addTestIterations(test, spec, TYPE_DRAW_COUNT); 645 646 this->addChild(test); 647 } 648 649 // Multiple attribute 650 { 651 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "multiple_attributes", "Multiple attribute arrays."); 652 gls::DrawTestSpec spec; 653 654 spec.apiType = glu::ApiType::es(3,1); 655 spec.primitive = m_primitive; 656 spec.primitiveCount = 5; 657 spec.drawMethod = m_method; 658 spec.indexType = m_indexType; 659 spec.indexPointerOffset = 0; 660 spec.indexStorage = m_indexStorage; 661 spec.first = 0; 662 spec.indexMin = 0; 663 spec.indexMax = 0; 664 spec.instanceCount = 1; 665 spec.indirectOffset = 0; 666 667 spec.attribs.resize(2); 668 669 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT; 670 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2; 671 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER; 672 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW; 673 spec.attribs[0].componentCount = 4; 674 spec.attribs[0].offset = 0; 675 spec.attribs[0].stride = 0; 676 spec.attribs[0].normalize = false; 677 spec.attribs[0].instanceDivisor = 0; 678 spec.attribs[0].useDefaultAttribute = false; 679 680 spec.attribs[1].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT; 681 spec.attribs[1].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2; 682 spec.attribs[1].storage = gls::DrawTestSpec::STORAGE_BUFFER; 683 spec.attribs[1].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW; 684 spec.attribs[1].componentCount = 2; 685 spec.attribs[1].offset = 0; 686 spec.attribs[1].stride = 0; 687 spec.attribs[1].normalize = false; 688 spec.attribs[1].instanceDivisor = 0; 689 spec.attribs[1].useDefaultAttribute = false; 690 691 addTestIterations(test, spec, TYPE_DRAW_COUNT); 692 693 this->addChild(test); 694 } 695 696 // Multiple attribute, second one divided 697 { 698 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "instanced_attributes", "Instanced attribute array."); 699 gls::DrawTestSpec spec; 700 701 spec.apiType = glu::ApiType::es(3,1); 702 spec.primitive = m_primitive; 703 spec.primitiveCount = 5; 704 spec.drawMethod = m_method; 705 spec.indexType = m_indexType; 706 spec.indexPointerOffset = 0; 707 spec.indexStorage = m_indexStorage; 708 spec.first = 0; 709 spec.indexMin = 0; 710 spec.indexMax = 0; 711 spec.instanceCount = 1; 712 spec.indirectOffset = 0; 713 714 spec.attribs.resize(3); 715 716 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT; 717 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2; 718 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER; 719 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW; 720 spec.attribs[0].componentCount = 4; 721 spec.attribs[0].offset = 0; 722 spec.attribs[0].stride = 0; 723 spec.attribs[0].normalize = false; 724 spec.attribs[0].instanceDivisor = 0; 725 spec.attribs[0].useDefaultAttribute = false; 726 727 // Add another position component so the instances wont be drawn on each other 728 spec.attribs[1].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT; 729 spec.attribs[1].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2; 730 spec.attribs[1].storage = gls::DrawTestSpec::STORAGE_BUFFER; 731 spec.attribs[1].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW; 732 spec.attribs[1].componentCount = 2; 733 spec.attribs[1].offset = 0; 734 spec.attribs[1].stride = 0; 735 spec.attribs[1].normalize = false; 736 spec.attribs[1].instanceDivisor = 1; 737 spec.attribs[1].useDefaultAttribute = false; 738 spec.attribs[1].additionalPositionAttribute = true; 739 740 // Instanced color 741 spec.attribs[2].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT; 742 spec.attribs[2].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2; 743 spec.attribs[2].storage = gls::DrawTestSpec::STORAGE_BUFFER; 744 spec.attribs[2].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW; 745 spec.attribs[2].componentCount = 3; 746 spec.attribs[2].offset = 0; 747 spec.attribs[2].stride = 0; 748 spec.attribs[2].normalize = false; 749 spec.attribs[2].instanceDivisor = 1; 750 spec.attribs[2].useDefaultAttribute = false; 751 752 addTestIterations(test, spec, TYPE_INSTANCE_COUNT); 753 754 this->addChild(test); 755 } 756 757 // Multiple attribute, second one default 758 { 759 gls::DrawTest* test = new gls::DrawTest(m_testCtx, m_context.getRenderContext(), "default_attribute", "Attribute specified with glVertexAttrib*."); 760 gls::DrawTestSpec spec; 761 762 spec.apiType = glu::ApiType::es(3,1); 763 spec.primitive = m_primitive; 764 spec.primitiveCount = 5; 765 spec.drawMethod = m_method; 766 spec.indexType = m_indexType; 767 spec.indexPointerOffset = 0; 768 spec.indexStorage = m_indexStorage; 769 spec.first = 0; 770 spec.indexMin = 0; 771 spec.indexMax = 0; 772 spec.instanceCount = 1; 773 spec.indirectOffset = 0; 774 775 spec.attribs.resize(2); 776 777 spec.attribs[0].inputType = gls::DrawTestSpec::INPUTTYPE_FLOAT; 778 spec.attribs[0].outputType = gls::DrawTestSpec::OUTPUTTYPE_VEC2; 779 spec.attribs[0].storage = gls::DrawTestSpec::STORAGE_BUFFER; 780 spec.attribs[0].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW; 781 spec.attribs[0].componentCount = 2; 782 spec.attribs[0].offset = 0; 783 spec.attribs[0].stride = 0; 784 spec.attribs[0].normalize = false; 785 spec.attribs[0].instanceDivisor = 0; 786 spec.attribs[0].useDefaultAttribute = false; 787 788 struct IOPair 789 { 790 gls::DrawTestSpec::InputType input; 791 gls::DrawTestSpec::OutputType output; 792 int componentCount; 793 } iopairs[] = 794 { 795 { gls::DrawTestSpec::INPUTTYPE_FLOAT, gls::DrawTestSpec::OUTPUTTYPE_VEC2, 4 }, 796 { gls::DrawTestSpec::INPUTTYPE_FLOAT, gls::DrawTestSpec::OUTPUTTYPE_VEC4, 2 }, 797 { gls::DrawTestSpec::INPUTTYPE_INT, gls::DrawTestSpec::OUTPUTTYPE_IVEC3, 4 }, 798 { gls::DrawTestSpec::INPUTTYPE_UNSIGNED_INT, gls::DrawTestSpec::OUTPUTTYPE_UVEC2, 4 }, 799 }; 800 801 for (int ioNdx = 0; ioNdx < DE_LENGTH_OF_ARRAY(iopairs); ++ioNdx) 802 { 803 const std::string desc = gls::DrawTestSpec::inputTypeToString(iopairs[ioNdx].input) + de::toString(iopairs[ioNdx].componentCount) + " to " + gls::DrawTestSpec::outputTypeToString(iopairs[ioNdx].output); 804 805 spec.attribs[1].inputType = iopairs[ioNdx].input; 806 spec.attribs[1].outputType = iopairs[ioNdx].output; 807 spec.attribs[1].storage = gls::DrawTestSpec::STORAGE_BUFFER; 808 spec.attribs[1].usage = gls::DrawTestSpec::USAGE_STATIC_DRAW; 809 spec.attribs[1].componentCount = iopairs[ioNdx].componentCount; 810 spec.attribs[1].offset = 0; 811 spec.attribs[1].stride = 0; 812 spec.attribs[1].normalize = false; 813 spec.attribs[1].instanceDivisor = 0; 814 spec.attribs[1].useDefaultAttribute = true; 815 816 test->addIteration(spec, desc.c_str()); 817 } 818 819 this->addChild(test); 820 } 821} 822 823class MethodGroup : public TestCaseGroup 824{ 825public: 826 MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod); 827 ~MethodGroup (void); 828 829 void init (void); 830 831private: 832 gls::DrawTestSpec::DrawMethod m_method; 833}; 834 835MethodGroup::MethodGroup (Context& context, const char* name, const char* descr, gls::DrawTestSpec::DrawMethod drawMethod) 836 : TestCaseGroup (context, name, descr) 837 , m_method (drawMethod) 838{ 839} 840 841MethodGroup::~MethodGroup (void) 842{ 843} 844 845void MethodGroup::init (void) 846{ 847 const bool indexed = (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX) 848 || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX) 849 || (m_method == gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX); 850 851 const gls::DrawTestSpec::Primitive primitive[] = 852 { 853 gls::DrawTestSpec::PRIMITIVE_POINTS, 854 gls::DrawTestSpec::PRIMITIVE_TRIANGLES, 855 gls::DrawTestSpec::PRIMITIVE_TRIANGLE_FAN, 856 gls::DrawTestSpec::PRIMITIVE_TRIANGLE_STRIP, 857 gls::DrawTestSpec::PRIMITIVE_LINES, 858 gls::DrawTestSpec::PRIMITIVE_LINE_STRIP, 859 gls::DrawTestSpec::PRIMITIVE_LINE_LOOP 860 }; 861 862 if (indexed) 863 { 864 // Index-tests 865 this->addChild(new IndexGroup(m_context, "indices", "Index tests", m_method)); 866 this->addChild(new BaseVertexGroup(m_context, "base_vertex", "Base vertex tests", m_method)); 867 this->addChild(new BuiltInVariableGroup(m_context, "builtin_variable", "Built in shader variable tests", m_method)); 868 } 869 870 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(primitive); ++ndx) 871 { 872 const std::string name = gls::DrawTestSpec::primitiveToString(primitive[ndx]); 873 const std::string desc = gls::DrawTestSpec::primitiveToString(primitive[ndx]); 874 875 this->addChild(new AttributeGroup(m_context, name.c_str(), desc.c_str(), m_method, primitive[ndx], gls::DrawTestSpec::INDEXTYPE_SHORT, gls::DrawTestSpec::STORAGE_BUFFER)); 876 } 877} 878 879} // anonymous 880 881DrawElementsBaseVertexTests::DrawElementsBaseVertexTests (Context& context) 882 : TestCaseGroup(context, "draw_base_vertex", "Base vertex extension drawing tests") 883{ 884} 885 886DrawElementsBaseVertexTests::~DrawElementsBaseVertexTests (void) 887{ 888} 889 890void DrawElementsBaseVertexTests::init (void) 891{ 892 const gls::DrawTestSpec::DrawMethod basicMethods[] = 893 { 894 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_BASEVERTEX, 895 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_RANGED_BASEVERTEX, 896 gls::DrawTestSpec::DRAWMETHOD_DRAWELEMENTS_INSTANCED_BASEVERTEX, 897 }; 898 899 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(basicMethods); ++ndx) 900 { 901 const std::string name = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]); 902 const std::string desc = gls::DrawTestSpec::drawMethodToString(basicMethods[ndx]); 903 904 this->addChild(new MethodGroup(m_context, name.c_str(), desc.c_str(), basicMethods[ndx])); 905 } 906} 907 908} // Functional 909} // gles31 910} // deqp 911