1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.1 Module 3 * ------------------------------------------------- 4 * 5 * Copyright 2014 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 Basic Layout Binding Tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es31fLayoutBindingTests.hpp" 25 26 #include "gluShaderProgram.hpp" 27 #include "gluPixelTransfer.hpp" 28 #include "gluTextureUtil.hpp" 29 30 #include "glwFunctions.hpp" 31 #include "glwEnums.hpp" 32 33 #include "tcuSurface.hpp" 34 #include "tcuTestLog.hpp" 35 #include "tcuTexture.hpp" 36 #include "tcuTextureUtil.hpp" 37 #include "tcuImageCompare.hpp" 38 #include "tcuStringTemplate.hpp" 39 #include "tcuRenderTarget.hpp" 40 41 #include "deString.h" 42 #include "deStringUtil.hpp" 43 #include "deRandom.hpp" 44 45 using tcu::TestLog; 46 using tcu::Vec2; 47 using tcu::Vec3; 48 using tcu::Vec4; 49 50 namespace deqp 51 { 52 namespace gles31 53 { 54 namespace Functional 55 { 56 namespace 57 { 58 59 enum TestType 60 { 61 TESTTYPE_BINDING_SINGLE = 0, 62 TESTTYPE_BINDING_MAX, 63 TESTTYPE_BINDING_MULTIPLE, 64 TESTTYPE_BINDING_ARRAY, 65 TESTTYPE_BINDING_MAX_ARRAY, 66 67 TESTTYPE_BINDING_LAST, 68 }; 69 70 enum ShaderType 71 { 72 SHADERTYPE_VERTEX = 0, 73 SHADERTYPE_FRAGMENT, 74 SHADERTYPE_BOTH, 75 76 SHADERTYPE_LAST, 77 }; 78 79 enum 80 { 81 MAX_UNIFORM_MULTIPLE_INSTANCES = 7, 82 MAX_UNIFORM_ARRAY_SIZE = 7, 83 }; 84 85 std::string generateVertexShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody) 86 { 87 static const char* const s_simpleVertexShaderSource = "#version 310 es\n" 88 "in highp vec4 a_position;\n" 89 "void main (void)\n" 90 "{\n" 91 " gl_Position = a_position;\n" 92 "}\n"; 93 94 switch (shaderType) 95 { 96 case SHADERTYPE_VERTEX: 97 case SHADERTYPE_BOTH: 98 { 99 std::ostringstream vertexShaderSource; 100 vertexShaderSource << "#version 310 es\n" 101 << "in highp vec4 a_position;\n" 102 << "out highp vec4 v_color;\n" 103 << "uniform highp int u_arrayNdx;\n\n" 104 << shaderUniformDeclarations << "\n" 105 << "void main (void)\n" 106 << "{\n" 107 << " highp vec4 color;\n\n" 108 << shaderBody << "\n" 109 << " v_color = color;\n" 110 << " gl_Position = a_position;\n" 111 << "}\n"; 112 113 return vertexShaderSource.str(); 114 } 115 116 case SHADERTYPE_FRAGMENT: 117 return s_simpleVertexShaderSource; 118 119 default: 120 DE_ASSERT(false); 121 return ""; 122 } 123 } 124 125 std::string generateFragmentShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody) 126 { 127 static const char* const s_simpleFragmentShaderSource = "#version 310 es\n" 128 "in highp vec4 v_color;\n" 129 "layout(location = 0) out highp vec4 fragColor;\n" 130 "void main (void)\n" 131 "{\n" 132 " fragColor = v_color;\n" 133 "}\n"; 134 135 switch (shaderType) 136 { 137 case SHADERTYPE_VERTEX: 138 return s_simpleFragmentShaderSource; 139 140 case SHADERTYPE_FRAGMENT: 141 { 142 std::ostringstream fragmentShaderSource; 143 fragmentShaderSource << "#version 310 es\n" 144 << "layout(location = 0) out highp vec4 fragColor;\n" 145 << "uniform highp int u_arrayNdx;\n\n" 146 << shaderUniformDeclarations << "\n" 147 << "void main (void)\n" 148 << "{\n" 149 << " highp vec4 color;\n\n" 150 << shaderBody << "\n" 151 << " fragColor = color;\n" 152 << "}\n"; 153 154 return fragmentShaderSource.str(); 155 } 156 case SHADERTYPE_BOTH: 157 { 158 std::ostringstream fragmentShaderSource; 159 fragmentShaderSource << "#version 310 es\n" 160 << "in highp vec4 v_color;\n" 161 << "layout(location = 0) out highp vec4 fragColor;\n" 162 << "uniform highp int u_arrayNdx;\n\n" 163 << shaderUniformDeclarations << "\n" 164 << "void main (void)\n" 165 << "{\n" 166 << " if (v_color.x > 2.0) discard;\n" 167 << " highp vec4 color;\n\n" 168 << shaderBody << "\n" 169 << " fragColor = color;\n" 170 << "}\n"; 171 172 return fragmentShaderSource.str(); 173 } 174 175 default: 176 DE_ASSERT(false); 177 return ""; 178 } 179 } 180 181 std::string getUniformName (const std::string& name, int declNdx) 182 { 183 return name + de::toString(declNdx); 184 } 185 186 std::string getUniformName (const std::string& name, int declNdx, int arrNdx) 187 { 188 return name + de::toString(declNdx) + "[" + de::toString(arrNdx) + "]"; 189 } 190 191 Vec4 getRandomColor (de::Random& rnd) 192 { 193 const float r = rnd.getFloat(0.2f, 0.9f); 194 const float g = rnd.getFloat(0.2f, 0.9f); 195 const float b = rnd.getFloat(0.2f, 0.9f); 196 return Vec4(r, g, b, 1.0f); 197 } 198 199 class LayoutBindingRenderCase : public TestCase 200 { 201 public: 202 enum 203 { 204 TEST_RENDER_WIDTH = 256, 205 TEST_RENDER_HEIGHT = 256, 206 TEST_TEXTURE_SIZE = 1, 207 }; 208 209 LayoutBindingRenderCase (Context& context, 210 const char* name, 211 const char* desc, 212 ShaderType shaderType, 213 TestType testType, 214 glw::GLenum maxBindingPointEnum, 215 glw::GLenum maxVertexUnitsEnum, 216 glw::GLenum maxFragmentUnitsEnum, 217 glw::GLenum maxCombinedUnitsEnum, 218 const std::string& uniformName); 219 virtual ~LayoutBindingRenderCase (void); 220 221 virtual void init (void); 222 virtual void deinit (void); 223 224 protected: 225 virtual glu::ShaderProgram* generateShaders (void) const = 0; 226 227 void initRenderState (void); 228 bool drawAndVerifyResult (const Vec4& expectedColor); 229 void setTestResult (bool queryTestPassed, bool imageTestPassed); 230 231 const glu::ShaderProgram* m_program; 232 const ShaderType m_shaderType; 233 const TestType m_testType; 234 const std::string m_uniformName; 235 236 const glw::GLenum m_maxBindingPointEnum; 237 const glw::GLenum m_maxVertexUnitsEnum; 238 const glw::GLenum m_maxFragmentUnitsEnum; 239 const glw::GLenum m_maxCombinedUnitsEnum; 240 241 glw::GLuint m_vertexBuffer; 242 glw::GLuint m_indexBuffer; 243 glw::GLint m_shaderProgramLoc; 244 glw::GLint m_shaderProgramPosLoc; 245 glw::GLint m_shaderProgramArrayNdxLoc; 246 glw::GLint m_numBindings; 247 248 std::vector<glw::GLint> m_bindings; 249 250 private: 251 void initBindingPoints (int minBindingPoint, int numBindingPoints); 252 }; 253 254 LayoutBindingRenderCase::LayoutBindingRenderCase (Context& context, 255 const char* name, 256 const char* desc, 257 ShaderType shaderType, 258 TestType testType, 259 glw::GLenum maxBindingPointEnum, 260 glw::GLenum maxVertexUnitsEnum, 261 glw::GLenum maxFragmentUnitsEnum, 262 glw::GLenum maxCombinedUnitsEnum, 263 const std::string& uniformName) 264 : TestCase (context, name, desc) 265 , m_program (DE_NULL) 266 , m_shaderType (shaderType) 267 , m_testType (testType) 268 , m_uniformName (uniformName) 269 , m_maxBindingPointEnum (maxBindingPointEnum) 270 , m_maxVertexUnitsEnum (maxVertexUnitsEnum) 271 , m_maxFragmentUnitsEnum (maxFragmentUnitsEnum) 272 , m_maxCombinedUnitsEnum (maxCombinedUnitsEnum) 273 , m_vertexBuffer (0) 274 , m_indexBuffer (0) 275 , m_shaderProgramLoc (0) 276 , m_shaderProgramPosLoc (0) 277 , m_shaderProgramArrayNdxLoc (0) 278 , m_numBindings (0) 279 { 280 } 281 282 LayoutBindingRenderCase::~LayoutBindingRenderCase (void) 283 { 284 deinit(); 285 } 286 287 void LayoutBindingRenderCase::init (void) 288 { 289 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 290 291 { 292 de::Random rnd (deStringHash(getName()) ^ 0xff23a4); 293 glw::GLint numBindingPoints = 0; // Number of available binding points 294 glw::GLint maxVertexUnits = 0; // Available uniforms in the vertex shader 295 glw::GLint maxFragmentUnits = 0; // Available uniforms in the fragment shader 296 glw::GLint maxCombinedUnits = 0; // Available uniforms in all the shader stages combined 297 glw::GLint maxUnits = 0; // Maximum available uniforms for this test 298 299 gl.getIntegerv(m_maxVertexUnitsEnum, &maxVertexUnits); 300 gl.getIntegerv(m_maxFragmentUnitsEnum, &maxFragmentUnits); 301 gl.getIntegerv(m_maxCombinedUnitsEnum, &maxCombinedUnits); 302 gl.getIntegerv(m_maxBindingPointEnum, &numBindingPoints); 303 GLU_EXPECT_NO_ERROR(gl.getError(), "Querying available uniform numbers failed"); 304 305 m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the vertex shader: " << maxVertexUnits << tcu::TestLog::EndMessage; 306 m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the fragment shader: " << maxFragmentUnits << tcu::TestLog::EndMessage; 307 m_testCtx.getLog() << tcu::TestLog::Message << "Maximum combined units for uniform type: " << maxCombinedUnits << tcu::TestLog::EndMessage; 308 m_testCtx.getLog() << tcu::TestLog::Message << "Maximum binding point for uniform type: " << numBindingPoints-1 << tcu::TestLog::EndMessage; 309 310 // Select maximum number of uniforms used for the test 311 switch (m_shaderType) 312 { 313 case SHADERTYPE_VERTEX: 314 maxUnits = maxVertexUnits; 315 break; 316 317 case SHADERTYPE_FRAGMENT: 318 maxUnits = maxFragmentUnits; 319 break; 320 321 case SHADERTYPE_BOTH: 322 maxUnits = maxCombinedUnits/2; 323 break; 324 325 default: 326 DE_ASSERT(false); 327 } 328 329 // Select the number of uniforms (= bindings) used for this test 330 switch (m_testType) 331 { 332 case TESTTYPE_BINDING_SINGLE: 333 case TESTTYPE_BINDING_MAX: 334 m_numBindings = 1; 335 break; 336 337 case TESTTYPE_BINDING_MULTIPLE: 338 if (maxUnits < 2) 339 throw tcu::NotSupportedError("Not enough uniforms available for test"); 340 m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_MULTIPLE_INSTANCES, maxUnits)); 341 break; 342 343 case TESTTYPE_BINDING_ARRAY: 344 case TESTTYPE_BINDING_MAX_ARRAY: 345 if (maxUnits < 2) 346 throw tcu::NotSupportedError("Not enough uniforms available for test"); 347 m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits)); 348 break; 349 350 default: 351 DE_ASSERT(false); 352 } 353 354 // Check that we have enough uniforms in different shaders to perform the tests 355 if ( ((m_shaderType == SHADERTYPE_VERTEX) || (m_shaderType == SHADERTYPE_BOTH)) && (maxVertexUnits < m_numBindings) ) 356 throw tcu::NotSupportedError("Vertex shader: not enough uniforms available for test"); 357 if ( ((m_shaderType == SHADERTYPE_FRAGMENT) || (m_shaderType == SHADERTYPE_BOTH)) && (maxFragmentUnits < m_numBindings) ) 358 throw tcu::NotSupportedError("Fragment shader: not enough uniforms available for test"); 359 if ( (m_shaderType == SHADERTYPE_BOTH) && (maxCombinedUnits < m_numBindings*2) ) 360 throw tcu::NotSupportedError("Not enough uniforms available for test"); 361 362 // Check that we have enough binding points to perform the tests 363 if (numBindingPoints < m_numBindings) 364 throw tcu::NotSupportedError("Not enough binding points available for test"); 365 366 // Initialize the binding points i.e. populate the two binding point vectors 367 initBindingPoints(0, numBindingPoints); 368 } 369 370 // Generate the shader program - note: this must be done after deciding the binding points 371 DE_ASSERT(!m_program); 372 m_testCtx.getLog() << tcu::TestLog::Message << "Creating test shaders" << tcu::TestLog::EndMessage; 373 m_program = generateShaders(); 374 m_testCtx.getLog() << *m_program; 375 376 if (!m_program->isOk()) 377 throw tcu::TestError("Shader compile failed"); 378 379 // Setup vertex and index buffers 380 { 381 // Get attribute and uniform locations 382 const deUint32 program = m_program->getProgram(); 383 384 m_shaderProgramPosLoc = gl.getAttribLocation(program, "a_position"); 385 m_shaderProgramArrayNdxLoc = gl.getUniformLocation(program, "u_arrayNdx"); 386 m_vertexBuffer = 0; 387 m_indexBuffer = 0; 388 389 // Setup buffers so that we render one quad covering the whole viewport 390 const Vec3 vertices[] = 391 { 392 Vec3(-1.0f, -1.0f, +1.0f), 393 Vec3(+1.0f, -1.0f, +1.0f), 394 Vec3(+1.0f, +1.0f, +1.0f), 395 Vec3(-1.0f, +1.0f, +1.0f), 396 }; 397 398 const deUint16 indices[] = 399 { 400 0, 1, 2, 401 0, 2, 3, 402 }; 403 404 TCU_CHECK((m_shaderProgramPosLoc >= 0) && (m_shaderProgramArrayNdxLoc >= 0)); 405 406 // Generate and bind index buffer 407 gl.genBuffers(1, &m_indexBuffer); 408 gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer); 409 gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (DE_LENGTH_OF_ARRAY(indices)*(glw::GLsizeiptr)sizeof(indices[0])), &indices[0], GL_STATIC_DRAW); 410 GLU_EXPECT_NO_ERROR(gl.getError(), "Index buffer setup failed"); 411 412 // Generate and bind vertex buffer 413 gl.genBuffers(1, &m_vertexBuffer); 414 gl.bindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer); 415 gl.bufferData(GL_ARRAY_BUFFER, (DE_LENGTH_OF_ARRAY(vertices)*(glw::GLsizeiptr)sizeof(vertices[0])), &vertices[0], GL_STATIC_DRAW); 416 gl.enableVertexAttribArray(m_shaderProgramPosLoc); 417 gl.vertexAttribPointer(m_shaderProgramPosLoc, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL); 418 GLU_EXPECT_NO_ERROR(gl.getError(), "Vertex buffer setup failed"); 419 } 420 } 421 422 void LayoutBindingRenderCase::deinit (void) 423 { 424 if (m_program) 425 { 426 delete m_program; 427 m_program = DE_NULL; 428 } 429 430 if (m_shaderProgramPosLoc) 431 m_context.getRenderContext().getFunctions().disableVertexAttribArray(m_shaderProgramPosLoc); 432 433 if (m_vertexBuffer) 434 { 435 m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_vertexBuffer); 436 m_context.getRenderContext().getFunctions().bindBuffer(GL_ARRAY_BUFFER, 0); 437 } 438 439 if (m_indexBuffer) 440 { 441 m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_indexBuffer); 442 m_context.getRenderContext().getFunctions().bindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 443 } 444 } 445 446 void LayoutBindingRenderCase::initBindingPoints (int minBindingPoint, int numBindingPoints) 447 { 448 de::Random rnd(deStringHash(getName()) ^ 0xff23a4); 449 450 switch (m_testType) 451 { 452 case TESTTYPE_BINDING_SINGLE: 453 { 454 const int bpoint = rnd.getInt(minBindingPoint, numBindingPoints-1); 455 m_bindings.push_back(bpoint); 456 break; 457 } 458 459 case TESTTYPE_BINDING_MAX: 460 m_bindings.push_back(numBindingPoints-1); 461 break; 462 463 case TESTTYPE_BINDING_MULTIPLE: 464 { 465 // Choose multiple unique binding points from the low and high end of available binding points 466 std::vector<deUint32> lowBindingPoints; 467 std::vector<deUint32> highBindingPoints; 468 469 for (int bpoint = 0; bpoint < numBindingPoints/2; ++bpoint) 470 lowBindingPoints.push_back(bpoint); 471 for (int bpoint = numBindingPoints/2; bpoint < numBindingPoints; ++bpoint) 472 highBindingPoints.push_back(bpoint); 473 474 rnd.shuffle(lowBindingPoints.begin(), lowBindingPoints.end()); 475 rnd.shuffle(highBindingPoints.begin(), highBindingPoints.end()); 476 477 for (int ndx = 0; ndx < m_numBindings; ++ndx) 478 { 479 if (ndx%2 == 0) 480 { 481 const int bpoint = lowBindingPoints.back(); 482 lowBindingPoints.pop_back(); 483 m_bindings.push_back(bpoint); 484 } 485 else 486 { 487 const int bpoint = highBindingPoints.back(); 488 highBindingPoints.pop_back(); 489 m_bindings.push_back(bpoint); 490 } 491 492 } 493 break; 494 } 495 496 case TESTTYPE_BINDING_ARRAY: 497 { 498 const glw::GLint binding = rnd.getInt(minBindingPoint, numBindingPoints-m_numBindings); 499 for (int ndx = 0; ndx < m_numBindings; ++ndx) 500 m_bindings.push_back(binding+ndx); 501 break; 502 } 503 504 case TESTTYPE_BINDING_MAX_ARRAY: 505 { 506 const glw::GLint binding = numBindingPoints-m_numBindings; 507 for (int ndx = 0; ndx < m_numBindings; ++ndx) 508 m_bindings.push_back(binding+ndx); 509 break; 510 } 511 512 default: 513 DE_ASSERT(false); 514 } 515 } 516 517 void LayoutBindingRenderCase::initRenderState (void) 518 { 519 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 520 521 gl.useProgram(m_program->getProgram()); 522 gl.viewport(0, 0, TEST_RENDER_WIDTH, TEST_RENDER_HEIGHT); 523 gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 524 GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to set render state"); 525 } 526 527 bool LayoutBindingRenderCase::drawAndVerifyResult (const Vec4& expectedColor) 528 { 529 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 530 const tcu::RGBA threshold = m_context.getRenderContext().getRenderTarget().getPixelFormat().getColorThreshold(); 531 tcu::Surface reference (TEST_RENDER_WIDTH, TEST_RENDER_HEIGHT); 532 533 gl.clear(GL_COLOR_BUFFER_BIT); 534 535 // Draw 536 gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL); 537 GLU_EXPECT_NO_ERROR(gl.getError(), "Drawing failed"); 538 539 // Verify 540 tcu::Surface result(TEST_RENDER_WIDTH, TEST_RENDER_HEIGHT); 541 m_testCtx.getLog() << TestLog::Message << "Reading pixels" << TestLog::EndMessage; 542 glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess()); 543 GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels failed"); 544 545 tcu::clear(reference.getAccess(), expectedColor); 546 m_testCtx.getLog() << tcu::TestLog::Message << "Verifying output image" << tcu::TestLog::EndMessage; 547 548 return tcu::pixelThresholdCompare(m_testCtx.getLog(), "Render result", "Result verification", reference, result, threshold, tcu::COMPARE_LOG_RESULT); 549 } 550 551 void LayoutBindingRenderCase::setTestResult (bool queryTestPassed, bool imageTestPassed) 552 { 553 if (queryTestPassed && imageTestPassed) 554 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 555 else if (!queryTestPassed && !imageTestPassed) 556 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more binding point queries and image comparisons failed"); 557 else if (!queryTestPassed) 558 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more binding point queries failed"); 559 else 560 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "One or more image comparisons failed"); 561 } 562 563 class LayoutBindingNegativeCase : public TestCase 564 { 565 public: 566 enum ErrorType 567 { 568 ERRORTYPE_OVER_MAX_UNITS = 0, 569 ERRORTYPE_LESS_THAN_ZERO, 570 ERRORTYPE_CONTRADICTORY, 571 572 ERRORTYPE_LAST, 573 }; 574 575 LayoutBindingNegativeCase (Context& context, 576 const char* name, 577 const char* desc, 578 ShaderType shaderType, 579 TestType testType, 580 ErrorType errorType, 581 glw::GLenum maxBindingPointEnum, 582 glw::GLenum maxVertexUnitsEnum, 583 glw::GLenum maxFragmentUnitsEnum, 584 glw::GLenum maxCombinedUnitsEnum, 585 const std::string& uniformName); 586 virtual ~LayoutBindingNegativeCase (void); 587 588 virtual void init (void); 589 virtual void deinit (void); 590 virtual IterateResult iterate (void); 591 592 protected: 593 virtual glu::ShaderProgram* generateShaders (void) const = 0; 594 595 const glu::ShaderProgram* m_program; 596 const ShaderType m_shaderType; 597 const TestType m_testType; 598 const ErrorType m_errorType; 599 const glw::GLenum m_maxBindingPointEnum; 600 const glw::GLenum m_maxVertexUnitsEnum; 601 const glw::GLenum m_maxFragmentUnitsEnum; 602 const glw::GLenum m_maxCombinedUnitsEnum; 603 const std::string m_uniformName; 604 glw::GLint m_numBindings; 605 std::vector<glw::GLint> m_vertexShaderBinding; 606 std::vector<glw::GLint> m_fragmentShaderBinding; 607 608 private: 609 void initBindingPoints (int minBindingPoint, int numBindingPoints); 610 }; 611 612 LayoutBindingNegativeCase::LayoutBindingNegativeCase (Context& context, 613 const char* name, 614 const char* desc, 615 ShaderType shaderType, 616 TestType testType, 617 ErrorType errorType, 618 glw::GLenum maxBindingPointEnum, 619 glw::GLenum maxVertexUnitsEnum, 620 glw::GLenum maxFragmentUnitsEnum, 621 glw::GLenum maxCombinedUnitsEnum, 622 const std::string& uniformName) 623 : TestCase (context, name, desc) 624 , m_program (DE_NULL) 625 , m_shaderType (shaderType) 626 , m_testType (testType) 627 , m_errorType (errorType) 628 , m_maxBindingPointEnum (maxBindingPointEnum) 629 , m_maxVertexUnitsEnum (maxVertexUnitsEnum) 630 , m_maxFragmentUnitsEnum (maxFragmentUnitsEnum) 631 , m_maxCombinedUnitsEnum (maxCombinedUnitsEnum) 632 , m_uniformName (uniformName) 633 , m_numBindings (0) 634 { 635 } 636 637 LayoutBindingNegativeCase::~LayoutBindingNegativeCase (void) 638 { 639 deinit(); 640 } 641 642 void LayoutBindingNegativeCase::init (void) 643 { 644 // Decide appropriate binding points for the vertex and fragment shaders 645 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 646 de::Random rnd (deStringHash(getName()) ^ 0xff23a4); 647 glw::GLint numBindingPoints = 0; // Number of binding points 648 glw::GLint maxVertexUnits = 0; // Available uniforms in the vertex shader 649 glw::GLint maxFragmentUnits = 0; // Available uniforms in the fragment shader 650 glw::GLint maxCombinedUnits = 0; // Available uniforms in all the shader stages combined 651 glw::GLint maxUnits = 0; // Maximum available uniforms for this test 652 653 gl.getIntegerv(m_maxVertexUnitsEnum, &maxVertexUnits); 654 gl.getIntegerv(m_maxFragmentUnitsEnum, &maxFragmentUnits); 655 gl.getIntegerv(m_maxCombinedUnitsEnum, &maxCombinedUnits); 656 gl.getIntegerv(m_maxBindingPointEnum, &numBindingPoints); 657 GLU_EXPECT_NO_ERROR(gl.getError(), "Querying available uniform numbers failed"); 658 659 m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the vertex shader: " << maxVertexUnits << tcu::TestLog::EndMessage; 660 m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the fragment shader: " << maxFragmentUnits << tcu::TestLog::EndMessage; 661 m_testCtx.getLog() << tcu::TestLog::Message << "Maximum combined units for uniform type: " << maxCombinedUnits << tcu::TestLog::EndMessage; 662 m_testCtx.getLog() << tcu::TestLog::Message << "Maximum binding point for uniform type: " << numBindingPoints-1 << tcu::TestLog::EndMessage; 663 664 // Select maximum number of uniforms used for the test 665 switch (m_shaderType) 666 { 667 case SHADERTYPE_VERTEX: 668 maxUnits = maxVertexUnits; 669 break; 670 671 case SHADERTYPE_FRAGMENT: 672 maxUnits = maxFragmentUnits; 673 break; 674 675 case SHADERTYPE_BOTH: 676 maxUnits = de::min(de::min(maxVertexUnits, maxFragmentUnits), maxCombinedUnits/2); 677 break; 678 679 default: 680 DE_ASSERT(false); 681 } 682 683 // Select the number of uniforms (= bindings) used for this test 684 switch (m_testType) 685 { 686 case TESTTYPE_BINDING_SINGLE: 687 case TESTTYPE_BINDING_MAX: 688 m_numBindings = 1; 689 break; 690 691 case TESTTYPE_BINDING_MULTIPLE: 692 case TESTTYPE_BINDING_ARRAY: 693 case TESTTYPE_BINDING_MAX_ARRAY: 694 if (m_errorType == ERRORTYPE_CONTRADICTORY) 695 { 696 // leave room for contradictory case 697 if (maxUnits < 3) 698 throw tcu::NotSupportedError("Not enough uniforms available for test"); 699 m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits-1)); 700 } 701 else 702 { 703 if (maxUnits < 2) 704 throw tcu::NotSupportedError("Not enough uniforms available for test"); 705 m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits)); 706 } 707 break; 708 709 default: 710 DE_ASSERT(false); 711 } 712 713 // Check that we have enough uniforms in different shaders to perform the tests 714 if ( ((m_shaderType == SHADERTYPE_VERTEX) || (m_shaderType == SHADERTYPE_BOTH)) && (maxVertexUnits < m_numBindings) ) 715 throw tcu::NotSupportedError("Vertex shader: not enough uniforms available for test"); 716 if ( ((m_shaderType == SHADERTYPE_FRAGMENT) || (m_shaderType == SHADERTYPE_BOTH)) && (maxFragmentUnits < m_numBindings) ) 717 throw tcu::NotSupportedError("Fragment shader: not enough uniforms available for test"); 718 if ( (m_shaderType == SHADERTYPE_BOTH) && (maxCombinedUnits < m_numBindings*2) ) 719 throw tcu::NotSupportedError("Not enough uniforms available for test"); 720 721 // Check that we have enough binding points to perform the tests 722 if (numBindingPoints < m_numBindings) 723 throw tcu::NotSupportedError("Not enough binding points available for test"); 724 if (m_errorType == ERRORTYPE_CONTRADICTORY && numBindingPoints == m_numBindings) 725 throw tcu::NotSupportedError("Not enough binding points available for test"); 726 727 // Initialize the binding points i.e. populate the two binding point vectors 728 initBindingPoints(0, numBindingPoints); 729 730 // Generate the shader program - note: this must be done after deciding the binding points 731 DE_ASSERT(!m_program); 732 m_testCtx.getLog() << tcu::TestLog::Message << "Creating test shaders" << tcu::TestLog::EndMessage; 733 m_program = generateShaders(); 734 m_testCtx.getLog() << *m_program; 735 } 736 737 void LayoutBindingNegativeCase::deinit (void) 738 { 739 if (m_program) 740 { 741 delete m_program; 742 m_program = DE_NULL; 743 } 744 } 745 746 TestCase::IterateResult LayoutBindingNegativeCase::iterate (void) 747 { 748 bool pass = false; 749 std::string failMessage; 750 751 switch (m_errorType) 752 { 753 case ERRORTYPE_CONTRADICTORY: // Contradictory binding points should cause a link-time error 754 if (!(m_program->getProgramInfo()).linkOk) 755 pass = true; 756 failMessage = "Test failed - expected a link-time error"; 757 break; 758 759 case ERRORTYPE_LESS_THAN_ZERO: // Out of bounds binding points should cause a compile-time error 760 case ERRORTYPE_OVER_MAX_UNITS: 761 if (!(m_program->getShaderInfo(glu::SHADERTYPE_VERTEX)).compileOk || !(m_program->getShaderInfo(glu::SHADERTYPE_FRAGMENT)).compileOk) 762 pass = true; 763 failMessage = "Test failed - expected a compile-time error"; 764 break; 765 766 default: 767 DE_ASSERT(false); 768 } 769 770 if (pass) 771 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 772 else 773 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, failMessage.c_str()); 774 775 return STOP; 776 } 777 778 void LayoutBindingNegativeCase::initBindingPoints (int minBindingPoint, int numBindingPoints) 779 { 780 de::Random rnd(deStringHash(getName()) ^ 0xff23a4); 781 782 switch (m_errorType) 783 { 784 case ERRORTYPE_OVER_MAX_UNITS: // Select a binding point that is 1 over the maximum 785 { 786 m_vertexShaderBinding.push_back(numBindingPoints+1-m_numBindings); 787 m_fragmentShaderBinding.push_back(numBindingPoints+1-m_numBindings); 788 break; 789 } 790 791 case ERRORTYPE_LESS_THAN_ZERO: // Select a random negative binding point 792 { 793 const glw::GLint binding = -rnd.getInt(1, m_numBindings); 794 m_vertexShaderBinding.push_back(binding); 795 m_fragmentShaderBinding.push_back(binding); 796 break; 797 } 798 799 case ERRORTYPE_CONTRADICTORY: // Select two valid, but contradictory binding points 800 { 801 m_vertexShaderBinding.push_back(minBindingPoint); 802 m_fragmentShaderBinding.push_back((minBindingPoint+1)%numBindingPoints); 803 DE_ASSERT(m_vertexShaderBinding.back() != m_fragmentShaderBinding.back()); 804 break; 805 } 806 807 default: 808 DE_ASSERT(false); 809 } 810 811 // In case we are testing with multiple uniforms populate the rest of the binding points 812 for (int ndx = 1; ndx < m_numBindings; ++ndx) 813 { 814 m_vertexShaderBinding.push_back(m_vertexShaderBinding.front()+ndx); 815 m_fragmentShaderBinding.push_back(m_fragmentShaderBinding.front()+ndx); 816 } 817 } 818 819 class SamplerBindingRenderCase : public LayoutBindingRenderCase 820 { 821 public: 822 SamplerBindingRenderCase (Context& context, const char* name, const char* desc, ShaderType shaderType, TestType testType, glw::GLenum samplerType, glw::GLenum textureType); 823 ~SamplerBindingRenderCase (void); 824 825 void init (void); 826 void deinit (void); 827 IterateResult iterate (void); 828 829 private: 830 glu::ShaderProgram* generateShaders (void) const; 831 glu::DataType getSamplerTexCoordType (void) const; 832 void initializeTexture (glw::GLint bindingPoint, glw::GLint textureName, const Vec4& color) const; 833 834 const glw::GLenum m_samplerType; 835 const glw::GLenum m_textureType; 836 837 std::vector<glw::GLuint> m_textures; 838 std::vector<Vec4> m_textureColors; 839 }; 840 841 842 SamplerBindingRenderCase::SamplerBindingRenderCase (Context& context, 843 const char* name, 844 const char* desc, 845 ShaderType shaderType, 846 TestType testType, 847 glw::GLenum samplerType, 848 glw::GLenum textureType) 849 : LayoutBindingRenderCase (context, name, desc, shaderType, testType, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, GL_MAX_TEXTURE_IMAGE_UNITS, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, "u_sampler") 850 , m_samplerType (samplerType) 851 , m_textureType (textureType) 852 { 853 } 854 855 SamplerBindingRenderCase::~SamplerBindingRenderCase (void) 856 { 857 deinit(); 858 } 859 860 void SamplerBindingRenderCase::init (void) 861 { 862 LayoutBindingRenderCase::init(); 863 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 864 de::Random rnd (deStringHash(getName()) ^ 0xff23a4); 865 866 867 // Initialize texture resources 868 m_textures = std::vector<glw::GLuint>(m_numBindings, 0); 869 870 // Texture colors 871 for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx) 872 m_textureColors.push_back(getRandomColor(rnd)); 873 874 // Textures 875 gl.genTextures((glw::GLsizei)m_textures.size(), &m_textures[0]); 876 877 for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx) 878 initializeTexture(m_bindings[texNdx], m_textures[texNdx], m_textureColors[texNdx]); 879 880 gl.activeTexture(GL_TEXTURE0); 881 } 882 883 void SamplerBindingRenderCase::deinit(void) 884 { 885 LayoutBindingRenderCase::deinit(); 886 887 // Clean up texture data 888 for (int i = 0; i < (int)m_textures.size(); ++i) 889 { 890 if (m_textures[i]) 891 { 892 m_context.getRenderContext().getFunctions().deleteTextures(1, &m_textures[i]); 893 m_context.getRenderContext().getFunctions().bindTexture(m_textureType, 0); 894 } 895 } 896 } 897 898 TestCase::IterateResult SamplerBindingRenderCase::iterate (void) 899 { 900 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 901 const int iterations = m_numBindings; 902 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY); 903 bool imageTestPassed = true; 904 bool queryTestPassed = true; 905 906 // Set the viewport and enable the shader program 907 initRenderState(); 908 909 for (int iterNdx = 0; iterNdx < iterations; ++iterNdx) 910 { 911 // Set the uniform value indicating the current array index 912 gl.uniform1i(m_shaderProgramArrayNdxLoc, iterNdx); 913 914 // Query binding point 915 const std::string name = arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx); 916 const glw::GLint binding = m_bindings[iterNdx]; 917 glw::GLint val = -1; 918 919 gl.getUniformiv(m_program->getProgram(), gl.getUniformLocation(m_program->getProgram(), name.c_str()), &val); 920 m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage; 921 GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed"); 922 923 // Draw and verify 924 if (val != binding) 925 queryTestPassed = false; 926 if (!drawAndVerifyResult(m_textureColors[iterNdx])) 927 imageTestPassed = false; 928 } 929 930 setTestResult(queryTestPassed, imageTestPassed); 931 return STOP; 932 } 933 934 glu::ShaderProgram* SamplerBindingRenderCase::generateShaders (void) const 935 { 936 std::ostringstream shaderUniformDecl; 937 std::ostringstream shaderBody; 938 939 const std::string texCoordType = glu::getDataTypeName(getSamplerTexCoordType()); 940 const std::string samplerType = glu::getDataTypeName(glu::getDataTypeFromGLType(m_samplerType)); 941 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY) ? true : false; 942 const int numDeclarations = arrayInstance ? 1 : m_numBindings; 943 944 // Generate the uniform declarations for the vertex and fragment shaders 945 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx) 946 { 947 shaderUniformDecl << "layout(binding = " << m_bindings[declNdx] << ") uniform highp " << samplerType << " " 948 << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n"; 949 } 950 951 // Generate the shader body for the vertex and fragment shaders 952 for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx) 953 { 954 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n" 955 << " {\n" 956 << " color = texture(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0.5));\n" 957 << " }\n"; 958 } 959 960 shaderBody << " else\n" 961 << " {\n" 962 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n" 963 << " }\n"; 964 965 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 966 << glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())) 967 << glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))); 968 } 969 970 void SamplerBindingRenderCase::initializeTexture (glw::GLint bindingPoint, glw::GLint textureName, const Vec4& color) const 971 { 972 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 973 974 gl.activeTexture(GL_TEXTURE0 + bindingPoint); 975 gl.bindTexture(m_textureType, textureName); 976 gl.texParameteri(m_textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 977 978 switch (m_textureType) 979 { 980 case GL_TEXTURE_2D: 981 { 982 tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE); 983 tcu::clear(level.getAccess(), color); 984 glu::texImage2D(m_context.getRenderContext(), m_textureType, 0, GL_RGBA8, level.getAccess()); 985 break; 986 } 987 988 case GL_TEXTURE_3D: 989 { 990 tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE); 991 tcu::clear(level.getAccess(), color); 992 glu::texImage3D(m_context.getRenderContext(), m_textureType, 0, GL_RGBA8, level.getAccess()); 993 break; 994 } 995 996 default: 997 DE_ASSERT(false); 998 } 999 1000 GLU_EXPECT_NO_ERROR(gl.getError(), "Texture initialization failed"); 1001 } 1002 1003 glu::DataType SamplerBindingRenderCase::getSamplerTexCoordType (void) const 1004 { 1005 switch (m_samplerType) 1006 { 1007 case GL_SAMPLER_2D: 1008 return glu::TYPE_FLOAT_VEC2; 1009 1010 case GL_SAMPLER_3D: 1011 return glu::TYPE_FLOAT_VEC3; 1012 1013 default: 1014 DE_ASSERT(false); 1015 return glu::TYPE_INVALID; 1016 } 1017 } 1018 1019 1020 class SamplerBindingNegativeCase : public LayoutBindingNegativeCase 1021 { 1022 public: 1023 SamplerBindingNegativeCase (Context& context, 1024 const char* name, 1025 const char* desc, 1026 ShaderType shaderType, 1027 TestType testType, 1028 ErrorType errorType, 1029 glw::GLenum samplerType); 1030 ~SamplerBindingNegativeCase (void); 1031 1032 private: 1033 glu::ShaderProgram* generateShaders (void) const; 1034 glu::DataType getSamplerTexCoordType (void) const; 1035 1036 const glw::GLenum m_samplerType; 1037 }; 1038 1039 SamplerBindingNegativeCase::SamplerBindingNegativeCase (Context& context, 1040 const char* name, 1041 const char* desc, 1042 ShaderType shaderType, 1043 TestType testType, 1044 ErrorType errorType, 1045 glw::GLenum samplerType) 1046 : LayoutBindingNegativeCase (context, name, desc, shaderType, testType, errorType, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, GL_MAX_TEXTURE_IMAGE_UNITS, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, "u_sampler") 1047 , m_samplerType (samplerType) 1048 { 1049 } 1050 1051 SamplerBindingNegativeCase::~SamplerBindingNegativeCase (void) 1052 { 1053 LayoutBindingNegativeCase::deinit(); 1054 } 1055 1056 glu::ShaderProgram* SamplerBindingNegativeCase::generateShaders (void) const 1057 { 1058 std::ostringstream vertexUniformDecl; 1059 std::ostringstream fragmentUniformDecl; 1060 std::ostringstream shaderBody; 1061 1062 const std::string texCoordType = glu::getDataTypeName(getSamplerTexCoordType()); 1063 const std::string samplerType = glu::getDataTypeName(glu::getDataTypeFromGLType(m_samplerType)); 1064 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY); 1065 const int numDeclarations = arrayInstance ? 1 : m_numBindings; 1066 1067 // Generate the uniform declarations for the vertex and fragment shaders 1068 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx) 1069 { 1070 vertexUniformDecl << "layout(binding = " << m_vertexShaderBinding[declNdx] << ") uniform highp " << samplerType 1071 << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n"; 1072 fragmentUniformDecl << "layout(binding = " << m_fragmentShaderBinding[declNdx] << ") uniform highp " << samplerType 1073 << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n"; 1074 } 1075 1076 // Generate the shader body for the vertex and fragment shaders 1077 for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx) 1078 { 1079 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n" 1080 << " {\n" 1081 << " color = texture(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0.5));\n" 1082 << " }\n"; 1083 } 1084 1085 shaderBody << " else\n" 1086 << " {\n" 1087 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n" 1088 << " }\n"; 1089 1090 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 1091 << glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str())) 1092 << glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str()))); 1093 } 1094 1095 glu::DataType SamplerBindingNegativeCase::getSamplerTexCoordType(void) const 1096 { 1097 switch (m_samplerType) 1098 { 1099 case GL_SAMPLER_2D: 1100 return glu::TYPE_FLOAT_VEC2; 1101 1102 case GL_SAMPLER_3D: 1103 return glu::TYPE_FLOAT_VEC3; 1104 1105 default: 1106 DE_ASSERT(false); 1107 return glu::TYPE_INVALID; 1108 } 1109 } 1110 1111 class ImageBindingRenderCase : public LayoutBindingRenderCase 1112 { 1113 public: 1114 ImageBindingRenderCase (Context& context, 1115 const char* name, 1116 const char* desc, 1117 ShaderType shaderType, 1118 TestType testType, 1119 glw::GLenum imageType, 1120 glw::GLenum textureType); 1121 ~ImageBindingRenderCase (void); 1122 1123 void init (void); 1124 void deinit (void); 1125 IterateResult iterate (void); 1126 1127 private: 1128 glu::ShaderProgram* generateShaders (void) const; 1129 void initializeImage (glw::GLint imageBindingPoint, glw::GLint textureBindingPoint, glw::GLint textureName, const Vec4& color) const; 1130 glu::DataType getImageTexCoordType (void) const; 1131 1132 const glw::GLenum m_imageType; 1133 const glw::GLenum m_textureType; 1134 1135 std::vector<glw::GLuint> m_textures; 1136 std::vector<Vec4> m_textureColors; 1137 }; 1138 1139 1140 ImageBindingRenderCase::ImageBindingRenderCase (Context& context, 1141 const char* name, 1142 const char* desc, 1143 ShaderType shaderType, 1144 TestType testType, 1145 glw::GLenum imageType, 1146 glw::GLenum textureType) 1147 : LayoutBindingRenderCase (context, name, desc, shaderType, testType, GL_MAX_IMAGE_UNITS, GL_MAX_VERTEX_IMAGE_UNIFORMS, GL_MAX_FRAGMENT_IMAGE_UNIFORMS, GL_MAX_COMBINED_IMAGE_UNIFORMS, "u_image") 1148 , m_imageType (imageType) 1149 , m_textureType (textureType) 1150 { 1151 } 1152 1153 ImageBindingRenderCase::~ImageBindingRenderCase (void) 1154 { 1155 deinit(); 1156 } 1157 1158 void ImageBindingRenderCase::init (void) 1159 { 1160 LayoutBindingRenderCase::init(); 1161 1162 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1163 de::Random rnd (deStringHash(getName()) ^ 0xff23a4); 1164 1165 // Initialize image / texture resources 1166 m_textures = std::vector<glw::GLuint>(m_numBindings, 0); 1167 1168 // Texture colors 1169 for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx) 1170 m_textureColors.push_back(getRandomColor(rnd)); 1171 1172 // Image textures 1173 gl.genTextures(m_numBindings, &m_textures[0]); 1174 1175 for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx) 1176 initializeImage(m_bindings[texNdx], texNdx, m_textures[texNdx], m_textureColors[texNdx]); 1177 } 1178 1179 void ImageBindingRenderCase::deinit (void) 1180 { 1181 LayoutBindingRenderCase::deinit(); 1182 1183 // Clean up texture data 1184 for (int texNdx = 0; texNdx < (int)m_textures.size(); ++texNdx) 1185 { 1186 if (m_textures[texNdx]) 1187 { 1188 m_context.getRenderContext().getFunctions().deleteTextures(1, &m_textures[texNdx]); 1189 m_context.getRenderContext().getFunctions().bindTexture(m_textureType, 0); 1190 } 1191 } 1192 } 1193 1194 TestCase::IterateResult ImageBindingRenderCase::iterate (void) 1195 { 1196 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1197 const int iterations = m_numBindings; 1198 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY); 1199 bool queryTestPassed = true; 1200 bool imageTestPassed = true; 1201 1202 // Set the viewport and enable the shader program 1203 initRenderState(); 1204 1205 for (int iterNdx = 0; iterNdx < iterations; ++iterNdx) 1206 { 1207 // Set the uniform value indicating the current array index 1208 gl.uniform1i(m_shaderProgramArrayNdxLoc, iterNdx); 1209 1210 const std::string name = (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx)); 1211 const glw::GLint binding = m_bindings[iterNdx]; 1212 glw::GLint val = -1; 1213 1214 gl.getUniformiv(m_program->getProgram(), gl.getUniformLocation(m_program->getProgram(), name.c_str()), &val); 1215 m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage; 1216 GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed"); 1217 1218 // Draw and verify 1219 if (val != binding) 1220 queryTestPassed = false; 1221 if (!drawAndVerifyResult(m_textureColors[iterNdx])) 1222 imageTestPassed = false; 1223 } 1224 1225 setTestResult(queryTestPassed, imageTestPassed); 1226 return STOP; 1227 } 1228 1229 void ImageBindingRenderCase::initializeImage (glw::GLint imageBindingPoint, glw::GLint textureBindingPoint, glw::GLint textureName, const Vec4& color) const 1230 { 1231 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1232 1233 gl.activeTexture(GL_TEXTURE0 + textureBindingPoint); 1234 gl.bindTexture(m_textureType, textureName); 1235 gl.texParameteri(m_textureType, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1236 1237 switch (m_textureType) 1238 { 1239 case GL_TEXTURE_2D: 1240 { 1241 tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE); 1242 tcu::clear(level.getAccess(), color); 1243 gl.texStorage2D(m_textureType, 1, GL_RGBA8, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE); 1244 gl.texSubImage2D(m_textureType, 0, 0, 0, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, level.getAccess().getDataPtr()); 1245 break; 1246 } 1247 1248 case GL_TEXTURE_3D: 1249 { 1250 tcu::TextureLevel level(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE); 1251 tcu::clear(level.getAccess(), color); 1252 gl.texStorage3D(m_textureType, 1, GL_RGBA8, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE); 1253 gl.texSubImage3D(m_textureType, 0, 0, 0, 0, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, level.getAccess().getDataPtr()); 1254 break; 1255 } 1256 1257 default: 1258 DE_ASSERT(false); 1259 } 1260 1261 gl.bindTexture(m_textureType, 0); 1262 gl.bindImageTexture(imageBindingPoint, textureName, 0, GL_TRUE, 0, GL_READ_ONLY, GL_RGBA8); 1263 GLU_EXPECT_NO_ERROR(gl.getError(), "Image initialization failed"); 1264 } 1265 1266 glu::ShaderProgram* ImageBindingRenderCase::generateShaders (void) const 1267 { 1268 std::ostringstream shaderUniformDecl; 1269 std::ostringstream shaderBody; 1270 1271 const std::string texCoordType = glu::getDataTypeName(getImageTexCoordType()); 1272 const std::string imageType = glu::getDataTypeName(glu::getDataTypeFromGLType(m_imageType)); 1273 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY) ? true : false; 1274 const int numDeclarations = (arrayInstance ? 1 : m_numBindings); 1275 1276 // Generate the uniform declarations for the vertex and fragment shaders 1277 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx) 1278 { 1279 shaderUniformDecl << "layout(rgba8, binding = " << m_bindings[declNdx] << ") uniform readonly highp " << imageType 1280 << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n"; 1281 } 1282 1283 // Generate the shader body for the vertex and fragment shaders 1284 for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx) 1285 { 1286 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n" 1287 << " {\n" 1288 << " color = imageLoad(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0));\n" 1289 << " }\n"; 1290 } 1291 1292 shaderBody << " else\n" 1293 << " {\n" 1294 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n" 1295 << " }\n"; 1296 1297 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 1298 << glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())) 1299 << glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))); 1300 } 1301 1302 glu::DataType ImageBindingRenderCase::getImageTexCoordType(void) const 1303 { 1304 switch (m_imageType) 1305 { 1306 case GL_IMAGE_2D: 1307 return glu::TYPE_INT_VEC2; 1308 1309 case GL_IMAGE_3D: 1310 return glu::TYPE_INT_VEC3; 1311 1312 default: 1313 DE_ASSERT(false); 1314 return glu::TYPE_INVALID; 1315 } 1316 } 1317 1318 1319 class ImageBindingNegativeCase : public LayoutBindingNegativeCase 1320 { 1321 public: 1322 ImageBindingNegativeCase (Context& context, 1323 const char* name, 1324 const char* desc, 1325 ShaderType shaderType, 1326 TestType testType, 1327 ErrorType errorType, 1328 glw::GLenum imageType); 1329 ~ImageBindingNegativeCase (void); 1330 1331 private: 1332 glu::ShaderProgram* generateShaders (void) const; 1333 glu::DataType getImageTexCoordType (void) const; 1334 1335 const glw::GLenum m_imageType; 1336 }; 1337 1338 ImageBindingNegativeCase::ImageBindingNegativeCase (Context& context, 1339 const char* name, 1340 const char* desc, 1341 ShaderType shaderType, 1342 TestType testType, 1343 ErrorType errorType, 1344 glw::GLenum imageType) 1345 : LayoutBindingNegativeCase (context, name, desc, shaderType, testType, errorType, GL_MAX_IMAGE_UNITS, GL_MAX_VERTEX_IMAGE_UNIFORMS, GL_MAX_FRAGMENT_IMAGE_UNIFORMS, GL_MAX_COMBINED_IMAGE_UNIFORMS, "u_image") 1346 , m_imageType (imageType) 1347 { 1348 } 1349 1350 ImageBindingNegativeCase::~ImageBindingNegativeCase (void) 1351 { 1352 deinit(); 1353 } 1354 1355 glu::ShaderProgram* ImageBindingNegativeCase::generateShaders (void) const 1356 { 1357 std::ostringstream vertexUniformDecl; 1358 std::ostringstream fragmentUniformDecl; 1359 std::ostringstream shaderBody; 1360 1361 const std::string texCoordType = glu::getDataTypeName(getImageTexCoordType()); 1362 const std::string imageType = glu::getDataTypeName(glu::getDataTypeFromGLType(m_imageType)); 1363 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY); 1364 const int numDeclarations = (arrayInstance ? 1 : m_numBindings); 1365 1366 // Generate the uniform declarations for the vertex and fragment shaders 1367 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx) 1368 { 1369 vertexUniformDecl << "layout(rgba8, binding = " << m_vertexShaderBinding[declNdx] << ") uniform readonly highp " << imageType 1370 << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n"; 1371 fragmentUniformDecl << "layout(rgba8, binding = " << m_fragmentShaderBinding[declNdx] << ") uniform readonly highp " << imageType 1372 << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n"; 1373 } 1374 1375 // Generate the shader body for the vertex and fragment shaders 1376 for (int bindNdx = 0; bindNdx < m_numBindings; ++bindNdx) 1377 { 1378 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n" 1379 << " {\n" 1380 << " color = imageLoad(" << (arrayInstance ? getUniformName(m_uniformName, 0, bindNdx) : getUniformName(m_uniformName, bindNdx)) << ", " << texCoordType << "(0));\n" 1381 << " }\n"; 1382 } 1383 1384 shaderBody << " else\n" 1385 << " {\n" 1386 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n" 1387 << " }\n"; 1388 1389 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 1390 << glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str())) 1391 << glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str()))); 1392 } 1393 1394 glu::DataType ImageBindingNegativeCase::getImageTexCoordType(void) const 1395 { 1396 switch (m_imageType) 1397 { 1398 case GL_IMAGE_2D: 1399 return glu::TYPE_INT_VEC2; 1400 1401 case GL_IMAGE_3D: 1402 return glu::TYPE_INT_VEC3; 1403 1404 default: 1405 DE_ASSERT(false); 1406 return glu::TYPE_INVALID; 1407 } 1408 } 1409 1410 1411 class UBOBindingRenderCase : public LayoutBindingRenderCase 1412 { 1413 public: 1414 UBOBindingRenderCase (Context& context, 1415 const char* name, 1416 const char* desc, 1417 ShaderType shaderType, 1418 TestType testType); 1419 ~UBOBindingRenderCase (void); 1420 1421 void init (void); 1422 void deinit (void); 1423 IterateResult iterate (void); 1424 1425 private: 1426 glu::ShaderProgram* generateShaders (void) const; 1427 1428 std::vector<deUint32> m_buffers; 1429 std::vector<Vec4> m_expectedColors; 1430 }; 1431 1432 UBOBindingRenderCase::UBOBindingRenderCase (Context& context, 1433 const char* name, 1434 const char* desc, 1435 ShaderType shaderType, 1436 TestType testType) 1437 : LayoutBindingRenderCase (context, name, desc, shaderType, testType, GL_MAX_UNIFORM_BUFFER_BINDINGS, GL_MAX_VERTEX_UNIFORM_BLOCKS, GL_MAX_FRAGMENT_UNIFORM_BLOCKS, GL_MAX_COMBINED_UNIFORM_BLOCKS, "ColorBlock") 1438 { 1439 } 1440 1441 UBOBindingRenderCase::~UBOBindingRenderCase (void) 1442 { 1443 deinit(); 1444 } 1445 1446 void UBOBindingRenderCase::init (void) 1447 { 1448 LayoutBindingRenderCase::init(); 1449 1450 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1451 de::Random rnd (deStringHash(getName()) ^ 0xff23a4); 1452 1453 // Initialize UBOs and related data 1454 m_buffers = std::vector<glw::GLuint>(m_numBindings, 0); 1455 gl.genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]); 1456 1457 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx) 1458 { 1459 m_expectedColors.push_back(getRandomColor(rnd)); 1460 m_expectedColors.push_back(getRandomColor(rnd)); 1461 } 1462 1463 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx) 1464 { 1465 gl.bindBuffer(GL_UNIFORM_BUFFER, m_buffers[bufNdx]); 1466 gl.bufferData(GL_UNIFORM_BUFFER, 2*sizeof(Vec4), &(m_expectedColors[2*bufNdx]), GL_STATIC_DRAW); 1467 gl.bindBufferBase(GL_UNIFORM_BUFFER, m_bindings[bufNdx], m_buffers[bufNdx]); 1468 } 1469 1470 GLU_EXPECT_NO_ERROR(gl.getError(), "UBO setup failed"); 1471 } 1472 1473 void UBOBindingRenderCase::deinit (void) 1474 { 1475 LayoutBindingRenderCase::deinit(); 1476 1477 // Clean up UBO data 1478 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx) 1479 { 1480 if (m_buffers[bufNdx]) 1481 { 1482 m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buffers[bufNdx]); 1483 m_context.getRenderContext().getFunctions().bindBuffer(GL_UNIFORM_BUFFER, 0); 1484 } 1485 } 1486 } 1487 1488 TestCase::IterateResult UBOBindingRenderCase::iterate (void) 1489 { 1490 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1491 const int iterations = m_numBindings; 1492 const glw::GLenum prop = GL_BUFFER_BINDING; 1493 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY); 1494 bool queryTestPassed = true; 1495 bool imageTestPassed = true; 1496 1497 // Set the viewport and enable the shader program 1498 initRenderState(); 1499 1500 for (int iterNdx = 0; iterNdx < iterations; ++iterNdx) 1501 { 1502 // Query binding point 1503 const std::string name = (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx)); 1504 const glw::GLint binding = m_bindings[iterNdx]; 1505 glw::GLint val = -1; 1506 1507 gl.getProgramResourceiv(m_program->getProgram(), GL_UNIFORM_BLOCK, gl.getProgramResourceIndex(m_program->getProgram(), GL_UNIFORM_BLOCK, name.c_str() ), 1, &prop, 1, DE_NULL, &val); 1508 m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage; 1509 GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed"); 1510 1511 if (val != binding) 1512 queryTestPassed = false; 1513 1514 // Draw twice to render both colors within the UBO 1515 for (int drawCycle = 0; drawCycle < 2; ++drawCycle) 1516 { 1517 // Set the uniform indicating the array index to be used and set the expected color 1518 const int arrayNdx = iterNdx*2 + drawCycle; 1519 gl.uniform1i(m_shaderProgramArrayNdxLoc, arrayNdx); 1520 1521 if (!drawAndVerifyResult(m_expectedColors[arrayNdx])) 1522 imageTestPassed = false; 1523 } 1524 } 1525 1526 setTestResult(queryTestPassed, imageTestPassed); 1527 return STOP; 1528 } 1529 1530 glu::ShaderProgram* UBOBindingRenderCase::generateShaders (void) const 1531 { 1532 std::ostringstream shaderUniformDecl; 1533 std::ostringstream shaderBody; 1534 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY); 1535 const int numDeclarations = (arrayInstance ? 1 : m_numBindings); 1536 1537 // Generate the uniform declarations for the vertex and fragment shaders 1538 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx) 1539 { 1540 shaderUniformDecl << "layout(std140, binding = " << m_bindings[declNdx] << ") uniform " 1541 << getUniformName(m_uniformName, declNdx) << "\n" 1542 << "{\n" 1543 << " highp vec4 color1;\n" 1544 << " highp vec4 color2;\n" 1545 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n"; 1546 } 1547 1548 // Generate the shader body for the vertex and fragment shaders 1549 for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx) // Multiply by two to cover cases for both colors for each UBO 1550 { 1551 const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2)); 1552 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n" 1553 << " {\n" 1554 << " color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n" 1555 << " }\n"; 1556 } 1557 1558 shaderBody << " else\n" 1559 << " {\n" 1560 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n" 1561 << " }\n"; 1562 1563 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 1564 << glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())) 1565 << glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))); 1566 } 1567 1568 1569 class UBOBindingNegativeCase : public LayoutBindingNegativeCase 1570 { 1571 public: 1572 UBOBindingNegativeCase (Context& context, 1573 const char* name, 1574 const char* desc, 1575 ShaderType shaderType, 1576 TestType testType, 1577 ErrorType errorType); 1578 ~UBOBindingNegativeCase (void); 1579 1580 private: 1581 glu::ShaderProgram* generateShaders (void) const; 1582 }; 1583 1584 UBOBindingNegativeCase::UBOBindingNegativeCase (Context& context, 1585 const char* name, 1586 const char* desc, 1587 ShaderType shaderType, 1588 TestType testType, 1589 ErrorType errorType) 1590 : LayoutBindingNegativeCase(context, name, desc, shaderType, testType, errorType, GL_MAX_UNIFORM_BUFFER_BINDINGS, GL_MAX_VERTEX_UNIFORM_BLOCKS, GL_MAX_FRAGMENT_UNIFORM_BLOCKS, GL_MAX_COMBINED_UNIFORM_BLOCKS, "ColorBlock") 1591 { 1592 } 1593 1594 UBOBindingNegativeCase::~UBOBindingNegativeCase (void) 1595 { 1596 deinit(); 1597 } 1598 1599 glu::ShaderProgram* UBOBindingNegativeCase::generateShaders (void) const 1600 { 1601 std::ostringstream vertexUniformDecl; 1602 std::ostringstream fragmentUniformDecl; 1603 std::ostringstream shaderBody; 1604 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY); 1605 const int numDeclarations = (arrayInstance ? 1 : m_numBindings); 1606 1607 // Generate the uniform declarations for the vertex and fragment shaders 1608 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx) 1609 { 1610 vertexUniformDecl << "layout(std140, binding = " << m_vertexShaderBinding[declNdx] << ") uniform " 1611 << getUniformName(m_uniformName, declNdx) << "\n" 1612 << "{\n" 1613 << " highp vec4 color1;\n" 1614 << " highp vec4 color2;\n" 1615 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n"; 1616 1617 fragmentUniformDecl << "layout(std140, binding = " << m_fragmentShaderBinding[declNdx] << ") uniform " 1618 << getUniformName(m_uniformName, declNdx) << "\n" 1619 << "{\n" 1620 << " highp vec4 color1;\n" 1621 << " highp vec4 color2;\n" 1622 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n"; 1623 } 1624 1625 // Generate the shader body for the vertex and fragment shaders 1626 for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx) // Multiply by two to cover cases for both colors for each UBO 1627 { 1628 const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2)); 1629 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n" 1630 << " {\n" 1631 << " color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n" 1632 << " }\n"; 1633 } 1634 1635 shaderBody << " else\n" 1636 << " {\n" 1637 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n" 1638 << " }\n"; 1639 1640 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 1641 << glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str())) 1642 << glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str()))); 1643 } 1644 1645 1646 class SSBOBindingRenderCase : public LayoutBindingRenderCase 1647 { 1648 public: 1649 SSBOBindingRenderCase (Context& context, 1650 const char* name, 1651 const char* desc, 1652 ShaderType shaderType, 1653 TestType testType); 1654 ~SSBOBindingRenderCase (void); 1655 1656 void init (void); 1657 void deinit (void); 1658 IterateResult iterate (void); 1659 1660 private: 1661 glu::ShaderProgram* generateShaders (void) const; 1662 1663 std::vector<glw::GLuint> m_buffers; 1664 std::vector<Vec4> m_expectedColors; 1665 }; 1666 1667 SSBOBindingRenderCase::SSBOBindingRenderCase (Context& context, 1668 const char* name, 1669 const char* desc, 1670 ShaderType shaderType, 1671 TestType testType) 1672 : LayoutBindingRenderCase (context, name, desc, shaderType, testType, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, "ColorBuffer") 1673 { 1674 } 1675 1676 SSBOBindingRenderCase::~SSBOBindingRenderCase (void) 1677 { 1678 deinit(); 1679 } 1680 1681 void SSBOBindingRenderCase::init (void) 1682 { 1683 LayoutBindingRenderCase::init(); 1684 1685 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1686 de::Random rnd (deStringHash(getName()) ^ 0xff23a4); 1687 1688 // Initialize SSBOs and related data 1689 m_buffers = std::vector<glw::GLuint>(m_numBindings, 0); 1690 gl.genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]); 1691 1692 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx) 1693 { 1694 m_expectedColors.push_back(getRandomColor(rnd)); 1695 m_expectedColors.push_back(getRandomColor(rnd)); 1696 } 1697 1698 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx) 1699 { 1700 gl.bindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffers[bufNdx]); 1701 gl.bufferData(GL_SHADER_STORAGE_BUFFER, 2*sizeof(Vec4), &(m_expectedColors[2*bufNdx]), GL_STATIC_DRAW); 1702 gl.bindBufferBase(GL_SHADER_STORAGE_BUFFER, m_bindings[bufNdx], m_buffers[bufNdx]); 1703 } 1704 1705 GLU_EXPECT_NO_ERROR(gl.getError(), "SSBO setup failed"); 1706 } 1707 1708 void SSBOBindingRenderCase::deinit (void) 1709 { 1710 LayoutBindingRenderCase::deinit(); 1711 1712 // Clean up SSBO data 1713 for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx) 1714 { 1715 if (m_buffers[bufNdx]) 1716 { 1717 m_context.getRenderContext().getFunctions().deleteBuffers(1, &m_buffers[bufNdx]); 1718 m_context.getRenderContext().getFunctions().bindBuffer(GL_SHADER_STORAGE_BUFFER, 0); 1719 m_buffers[bufNdx] = 0; 1720 } 1721 } 1722 } 1723 1724 TestCase::IterateResult SSBOBindingRenderCase::iterate (void) 1725 { 1726 const glw::Functions& gl = m_context.getRenderContext().getFunctions(); 1727 const int iterations = m_numBindings; 1728 const glw::GLenum prop = GL_BUFFER_BINDING; 1729 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY); 1730 bool queryTestPassed = true; 1731 bool imageTestPassed = true; 1732 1733 initRenderState(); 1734 1735 for (int iterNdx = 0; iterNdx < iterations; ++iterNdx) 1736 { 1737 // Query binding point 1738 const std::string name = (arrayInstance ? getUniformName(m_uniformName, 0, iterNdx) : getUniformName(m_uniformName, iterNdx)); 1739 const glw::GLint binding = m_bindings[iterNdx]; 1740 glw::GLint val = -1; 1741 1742 gl.getProgramResourceiv(m_program->getProgram(), GL_SHADER_STORAGE_BLOCK, gl.getProgramResourceIndex(m_program->getProgram(), GL_SHADER_STORAGE_BLOCK, name.c_str() ), 1, &prop, 1, DE_NULL, &val); 1743 m_testCtx.getLog() << tcu::TestLog::Message << "Querying binding point for " << name << ": " << val << " == " << binding << tcu::TestLog::EndMessage; 1744 GLU_EXPECT_NO_ERROR(gl.getError(), "Binding point query failed"); 1745 1746 if (val != binding) 1747 queryTestPassed = false; 1748 1749 // Draw twice to render both colors within the SSBO 1750 for (int drawCycle = 0; drawCycle < 2; ++drawCycle) 1751 { 1752 // Set the uniform indicating the array index to be used and set the expected color 1753 const int arrayNdx = iterNdx*2 + drawCycle; 1754 gl.uniform1i(m_shaderProgramArrayNdxLoc, arrayNdx); 1755 1756 if (!drawAndVerifyResult(m_expectedColors[arrayNdx])) 1757 imageTestPassed = false; 1758 } 1759 } 1760 1761 setTestResult(queryTestPassed, imageTestPassed); 1762 return STOP; 1763 } 1764 1765 glu::ShaderProgram* SSBOBindingRenderCase::generateShaders (void) const 1766 { 1767 std::ostringstream shaderUniformDecl; 1768 std::ostringstream shaderBody; 1769 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY); 1770 const int numDeclarations = (arrayInstance ? 1 : m_numBindings); 1771 1772 // Generate the uniform declarations for the vertex and fragment shaders 1773 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx) 1774 { 1775 shaderUniformDecl << "layout(std140, binding = " << m_bindings[declNdx] << ") buffer " 1776 << getUniformName(m_uniformName, declNdx) << "\n" 1777 << "{\n" 1778 << " highp vec4 color1;\n" 1779 << " highp vec4 color2;\n" 1780 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n"; 1781 } 1782 1783 // Generate the shader body for the vertex and fragment shaders 1784 for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx) // Multiply by two to cover cases for both colors for each UBO 1785 { 1786 const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2)); 1787 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n" 1788 << " {\n" 1789 << " color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n" 1790 << " }\n"; 1791 } 1792 1793 shaderBody << " else\n" 1794 << " {\n" 1795 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n" 1796 << " }\n"; 1797 1798 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 1799 << glu::VertexSource(generateVertexShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str())) 1800 << glu::FragmentSource(generateFragmentShader(m_shaderType, shaderUniformDecl.str(), shaderBody.str()))); 1801 } 1802 1803 1804 class SSBOBindingNegativeCase : public LayoutBindingNegativeCase 1805 { 1806 public: 1807 SSBOBindingNegativeCase (Context& context, 1808 const char* name, 1809 const char* desc, 1810 ShaderType shaderType, 1811 TestType testType, 1812 ErrorType errorType); 1813 ~SSBOBindingNegativeCase (void); 1814 1815 private: 1816 glu::ShaderProgram* generateShaders (void) const; 1817 }; 1818 1819 SSBOBindingNegativeCase::SSBOBindingNegativeCase (Context& context, 1820 const char* name, 1821 const char* desc, 1822 ShaderType shaderType, 1823 TestType testType, 1824 ErrorType errorType) 1825 : LayoutBindingNegativeCase(context, name, desc, shaderType, testType, errorType, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, "ColorBuffer") 1826 { 1827 } 1828 1829 SSBOBindingNegativeCase::~SSBOBindingNegativeCase (void) 1830 { 1831 deinit(); 1832 } 1833 1834 glu::ShaderProgram* SSBOBindingNegativeCase::generateShaders (void) const 1835 { 1836 std::ostringstream vertexUniformDecl; 1837 std::ostringstream fragmentUniformDecl; 1838 std::ostringstream shaderBody; 1839 const bool arrayInstance = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY); 1840 const int numDeclarations = (arrayInstance ? 1 : m_numBindings); 1841 1842 // Generate the uniform declarations for the vertex and fragment shaders 1843 for (int declNdx = 0; declNdx < numDeclarations; ++declNdx) 1844 { 1845 vertexUniformDecl << "layout(std140, binding = " << m_vertexShaderBinding[declNdx] << ") buffer " 1846 << getUniformName(m_uniformName, declNdx) << "\n" 1847 << "{\n" 1848 << " highp vec4 color1;\n" 1849 << " highp vec4 color2;\n" 1850 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n"; 1851 1852 fragmentUniformDecl << "layout(std140, binding = " << m_fragmentShaderBinding[declNdx] << ") buffer " 1853 << getUniformName(m_uniformName, declNdx) << "\n" 1854 << "{\n" 1855 << " highp vec4 color1;\n" 1856 << " highp vec4 color2;\n" 1857 << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n"; 1858 } 1859 1860 // Generate the shader body for the vertex and fragment shaders 1861 for (int bindNdx = 0; bindNdx < m_numBindings*2; ++bindNdx) // Multiply by two to cover cases for both colors for each UBO 1862 { 1863 const std::string uname = (arrayInstance ? getUniformName("colors", 0, bindNdx/2) : getUniformName("colors", bindNdx/2)); 1864 shaderBody << " " << (bindNdx == 0 ? "if" : "else if") << " (u_arrayNdx == " << de::toString(bindNdx) << ")\n" 1865 << " {\n" 1866 << " color = " << uname << (bindNdx%2 == 0 ? ".color1" : ".color2") << ";\n" 1867 << " }\n"; 1868 } 1869 1870 shaderBody << " else\n" 1871 << " {\n" 1872 << " color = vec4(0.0, 0.0, 0.0, 1.0);\n" 1873 << " }\n"; 1874 1875 return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() 1876 << glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str())) 1877 << glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str()))); 1878 } 1879 1880 1881 } // Anonymous 1882 1883 LayoutBindingTests::LayoutBindingTests (Context& context) 1884 : TestCaseGroup (context, "layout_binding", "Layout binding tests") 1885 { 1886 } 1887 1888 LayoutBindingTests::~LayoutBindingTests (void) 1889 { 1890 } 1891 1892 void LayoutBindingTests::init (void) 1893 { 1894 // Render test groups 1895 tcu::TestCaseGroup* const samplerBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "sampler", "Test sampler layout binding"); 1896 tcu::TestCaseGroup* const sampler2dBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "sampler2d", "Test sampler2d layout binding"); 1897 tcu::TestCaseGroup* const sampler3dBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "sampler3d", "Test sampler3d layout binding"); 1898 1899 tcu::TestCaseGroup* const imageBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "image", "Test image layout binding"); 1900 tcu::TestCaseGroup* const image2dBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "image2d", "Test image2d layout binding"); 1901 tcu::TestCaseGroup* const image3dBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "image3d", "Test image3d layout binding"); 1902 1903 tcu::TestCaseGroup* const UBOBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "ubo", "Test UBO layout binding"); 1904 tcu::TestCaseGroup* const SSBOBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "ssbo", "Test SSBO layout binding"); 1905 1906 // Negative test groups 1907 tcu::TestCaseGroup* const negativeBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "negative", "Test layout binding with invalid bindings"); 1908 1909 tcu::TestCaseGroup* const negativeSamplerBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "sampler", "Test sampler layout binding with invalid bindings"); 1910 tcu::TestCaseGroup* const negativeSampler2dBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "sampler2d", "Test sampler2d layout binding with invalid bindings"); 1911 tcu::TestCaseGroup* const negativeSampler3dBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "sampler3d", "Test sampler3d layout binding with invalid bindings"); 1912 1913 tcu::TestCaseGroup* const negativeImageBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "image", "Test image layout binding with invalid bindings"); 1914 tcu::TestCaseGroup* const negativeImage2dBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "image2d", "Test image2d layout binding with invalid bindings"); 1915 tcu::TestCaseGroup* const negativeImage3dBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "image3d", "Test image3d layout binding with invalid bindings"); 1916 1917 tcu::TestCaseGroup* const negativeUBOBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "ubo", "Test UBO layout binding with invalid bindings"); 1918 tcu::TestCaseGroup* const negativeSSBOBindingTestGroup = new tcu::TestCaseGroup(m_testCtx, "ssbo", "Test SSBO layout binding with invalid bindings"); 1919 1920 static const struct RenderTestType 1921 { 1922 ShaderType shaderType; 1923 TestType testType; 1924 std::string name; 1925 std::string descPostfix; 1926 } s_renderTestTypes[] = 1927 { 1928 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_SINGLE, "vertex_binding_single", "a single instance" }, 1929 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_MAX, "vertex_binding_max", "maximum binding point" }, 1930 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_MULTIPLE, "vertex_binding_multiple", "multiple instances"}, 1931 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_ARRAY, "vertex_binding_array", "an array instance" }, 1932 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_MAX_ARRAY, "vertex_binding_max_array", "an array instance with maximum binding point" }, 1933 1934 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_SINGLE, "fragment_binding_single", "a single instance" }, 1935 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_MAX, "fragment_binding_max", "maximum binding point" }, 1936 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_MULTIPLE, "fragment_binding_multiple", "multiple instances"}, 1937 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_ARRAY, "fragment_binding_array", "an array instance" }, 1938 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_MAX_ARRAY, "fragment_binding_max_array", "an array instance with maximum binding point" }, 1939 }; 1940 1941 static const struct NegativeTestType 1942 { 1943 ShaderType shaderType; 1944 TestType testType; 1945 LayoutBindingNegativeCase::ErrorType errorType; 1946 std::string name; 1947 std::string descPostfix; 1948 } s_negativeTestTypes[] = 1949 { 1950 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_SINGLE, LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS, "vertex_binding_over_max", "over maximum binding point"}, 1951 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_SINGLE, LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS, "fragment_binding_over_max", "over maximum binding point"}, 1952 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_SINGLE, LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO, "vertex_binding_neg", "negative binding point"}, 1953 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_SINGLE, LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO, "fragment_binding_neg", "negative binding point"}, 1954 1955 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_ARRAY, LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS, "vertex_binding_over_max_array", "over maximum binding point"}, 1956 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_ARRAY, LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS, "fragment_binding_over_max_array", "over maximum binding point"}, 1957 { SHADERTYPE_VERTEX, TESTTYPE_BINDING_ARRAY, LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO, "vertex_binding_neg_array", "negative binding point"}, 1958 { SHADERTYPE_FRAGMENT, TESTTYPE_BINDING_ARRAY, LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO, "fragment_binding_neg_array", "negative binding point"}, 1959 1960 { SHADERTYPE_BOTH, TESTTYPE_BINDING_SINGLE, LayoutBindingNegativeCase::ERRORTYPE_CONTRADICTORY, "binding_contradictory", "contradictory binding points"}, 1961 { SHADERTYPE_BOTH, TESTTYPE_BINDING_ARRAY, LayoutBindingNegativeCase::ERRORTYPE_CONTRADICTORY, "binding_contradictory_array", "contradictory binding points"}, 1962 }; 1963 1964 // Render tests 1965 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_renderTestTypes); ++testNdx) 1966 { 1967 const RenderTestType& test = s_renderTestTypes[testNdx]; 1968 1969 // Render sampler binding tests 1970 sampler2dBindingTestGroup->addChild(new SamplerBindingRenderCase(m_context, test.name.c_str(), ("Sampler2D layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType, GL_SAMPLER_2D, GL_TEXTURE_2D)); 1971 sampler3dBindingTestGroup->addChild(new SamplerBindingRenderCase(m_context, test.name.c_str(), ("Sampler3D layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType, GL_SAMPLER_3D, GL_TEXTURE_3D)); 1972 1973 // Render image binding tests 1974 image2dBindingTestGroup->addChild(new ImageBindingRenderCase(m_context, test.name.c_str(), ("Image2D layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType, GL_IMAGE_2D, GL_TEXTURE_2D)); 1975 image3dBindingTestGroup->addChild(new ImageBindingRenderCase(m_context, test.name.c_str(), ("Image3D layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType, GL_IMAGE_3D, GL_TEXTURE_3D)); 1976 1977 // Render UBO binding tests 1978 UBOBindingTestGroup->addChild(new UBOBindingRenderCase(m_context, test.name.c_str(), ("UBO layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType)); 1979 1980 // Render SSBO binding tests 1981 SSBOBindingTestGroup->addChild(new SSBOBindingRenderCase(m_context, test.name.c_str(), ("SSBO layout binding with " + test.descPostfix).c_str(), test.shaderType, test.testType)); 1982 } 1983 1984 // Negative binding tests 1985 for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_negativeTestTypes); ++testNdx) 1986 { 1987 const NegativeTestType& test = s_negativeTestTypes[testNdx]; 1988 1989 // Negative sampler binding tests 1990 negativeSampler2dBindingTestGroup->addChild(new SamplerBindingNegativeCase(m_context, test.name.c_str(), ("Invalid sampler2d layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType, GL_SAMPLER_2D)); 1991 negativeSampler3dBindingTestGroup->addChild(new SamplerBindingNegativeCase(m_context, test.name.c_str(), ("Invalid sampler3d layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType, GL_SAMPLER_3D)); 1992 1993 // Negative image binding tests 1994 negativeImage2dBindingTestGroup->addChild(new ImageBindingNegativeCase(m_context, test.name.c_str(), ("Invalid image2d layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType, GL_IMAGE_2D)); 1995 negativeImage3dBindingTestGroup->addChild(new ImageBindingNegativeCase(m_context, test.name.c_str(), ("Invalid image3d layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType, GL_IMAGE_3D)); 1996 1997 // Negative UBO binding tests 1998 negativeUBOBindingTestGroup->addChild(new UBOBindingNegativeCase(m_context, test.name.c_str(), ("Invalid UBO layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType)); 1999 2000 // Negative SSBO binding tests 2001 negativeSSBOBindingTestGroup->addChild(new SSBOBindingNegativeCase(m_context, test.name.c_str(), ("Invalid SSBO layout binding using " + test.descPostfix).c_str(), test.shaderType, test.testType, test.errorType)); 2002 } 2003 2004 samplerBindingTestGroup->addChild(sampler2dBindingTestGroup); 2005 samplerBindingTestGroup->addChild(sampler3dBindingTestGroup); 2006 2007 imageBindingTestGroup->addChild(image2dBindingTestGroup); 2008 imageBindingTestGroup->addChild(image3dBindingTestGroup); 2009 2010 negativeSamplerBindingTestGroup->addChild(negativeSampler2dBindingTestGroup); 2011 negativeSamplerBindingTestGroup->addChild(negativeSampler3dBindingTestGroup); 2012 2013 negativeImageBindingTestGroup->addChild(negativeImage2dBindingTestGroup); 2014 negativeImageBindingTestGroup->addChild(negativeImage3dBindingTestGroup); 2015 2016 negativeBindingTestGroup->addChild(negativeSamplerBindingTestGroup); 2017 negativeBindingTestGroup->addChild(negativeUBOBindingTestGroup); 2018 negativeBindingTestGroup->addChild(negativeSSBOBindingTestGroup); 2019 negativeBindingTestGroup->addChild(negativeImageBindingTestGroup); 2020 2021 addChild(samplerBindingTestGroup); 2022 addChild(UBOBindingTestGroup); 2023 addChild(SSBOBindingTestGroup); 2024 addChild(imageBindingTestGroup); 2025 addChild(negativeBindingTestGroup); 2026 } 2027 2028 } // Functional 2029 } // gles31 2030 } // deqp 2031