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 Framebuffer without attachments (GL_ARB_framebuffer_no_attachments) tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es31fFboNoAttachmentTests.hpp" 25 26 #include "glwDefs.hpp" 27 #include "glwEnums.hpp" 28 #include "glwFunctions.hpp" 29 30 #include "gluRenderContext.hpp" 31 #include "gluDefs.hpp" 32 #include "gluShaderProgram.hpp" 33 34 #include "tcuTestContext.hpp" 35 #include "tcuVectorType.hpp" 36 #include "tcuVectorUtil.hpp" 37 #include "tcuTestLog.hpp" 38 #include "tcuCommandLine.hpp" 39 40 #include "deMemory.h" 41 #include "deRandom.hpp" 42 #include "deString.h" 43 #include "deStringUtil.hpp" 44 45 #include <string> 46 #include <vector> 47 48 namespace deqp 49 { 50 namespace gles31 51 { 52 namespace Functional 53 { 54 namespace 55 { 56 57 using namespace glw; 58 59 using tcu::IVec2; 60 using tcu::TestLog; 61 62 using std::stringstream; 63 using std::string; 64 using std::vector; 65 66 bool checkFramebufferSize (TestLog& log, const glu::RenderContext& renderCtx, GLuint framebuffer, const IVec2& size) 67 { 68 const glw::Functions& gl = renderCtx.getFunctions(); 69 70 const char* const vertexSource = "#version 310 es\n" 71 "in layout(location = 0) highp vec2 a_position;\n\n" 72 "void main()\n" 73 "{\n" 74 " gl_Position = vec4(a_position, 0.0, 1.0);\n" 75 "}\n"; 76 77 const char* const fragmentSource = "#version 310 es\n" 78 "uniform layout(location = 0) highp ivec2 u_expectedSize;\n" 79 "out layout(location = 0) mediump vec4 f_color;\n\n" 80 "void main()\n" 81 "{\n" 82 " if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;\n" 83 " f_color = vec4(1.0, 0.5, 0.25, 1.0);\n" 84 "}\n"; 85 86 const glu::ShaderProgram program (renderCtx, glu::makeVtxFragSources(vertexSource, fragmentSource)); 87 GLuint query = 0; 88 GLuint insidePassed = 0; 89 GLuint outsideXPassed = 0; 90 GLuint outsideYPassed = 0; 91 92 if (!program.isOk()) 93 log << program; 94 95 TCU_CHECK(program.isOk()); 96 97 gl.useProgram(program.getProgram()); 98 gl.enable(GL_DEPTH_TEST); 99 gl.depthFunc(GL_ALWAYS); 100 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer); 101 gl.viewport(0, 0, size.x()*2, size.y()*2); // Oversized viewport so that it will not accidentally limit us to the correct size 102 103 log << TestLog::Message << "Using " << size.x()*2 << "x" << size.y()*2 << " viewport" << TestLog::EndMessage; 104 log << TestLog::Message << "Discarding fragments outside pixel of interest" << TestLog::EndMessage; 105 log << TestLog::Message << "Using occlusion query to check for rendered fragments" << TestLog::EndMessage; 106 107 TCU_CHECK(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); 108 109 // Render 110 { 111 const float data[] = 112 { 113 1.0f, 1.0f, 114 1.0f, -1.0f, 115 -1.0f, 1.0f, 116 -1.0f, 1.0f, 117 1.0f, -1.0f, 118 -1.0f, -1.0f, 119 }; 120 121 GLuint vertexArray = 0; 122 GLuint vertexBuffer = 0; 123 124 gl.genQueries(1, &query); 125 gl.genVertexArrays(1, &vertexArray); 126 gl.bindVertexArray(vertexArray); 127 128 gl.genBuffers(1, &vertexBuffer); 129 gl.bindBuffer(GL_ARRAY_BUFFER, vertexBuffer); 130 gl.bufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); 131 132 gl.enableVertexAttribArray(0); 133 gl.vertexAttribPointer(0, 2, GL_FLOAT, false, 0, DE_NULL); 134 135 gl.uniform2i(0, size.x()-1, size.y()-1); 136 gl.beginQuery(GL_ANY_SAMPLES_PASSED, query); 137 gl.drawArrays(GL_TRIANGLES, 0, 6); 138 gl.endQuery(GL_ANY_SAMPLES_PASSED); 139 gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &insidePassed); 140 log << TestLog::Message << "A fragment was not discarded at (" << size.x()-1 << ", " << size.y()-1 << "). " 141 << "Occlusion query reports it was " << (insidePassed > 0 ? "rendered." : "not rendered") << TestLog::EndMessage; 142 143 gl.uniform2i(0, size.x(), size.y()-1); 144 gl.beginQuery(GL_ANY_SAMPLES_PASSED, query); 145 gl.drawArrays(GL_TRIANGLES, 0, 6); 146 gl.endQuery(GL_ANY_SAMPLES_PASSED); 147 gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &outsideXPassed); 148 log << TestLog::Message << "A fragment was not discarded at (" << size.x() << ", " << size.y()-1 << "). " 149 << "Occlusion query reports it was " << (outsideXPassed > 0 ? "rendered." : "not rendered") << TestLog::EndMessage; 150 151 gl.uniform2i(0, size.x()-1, size.y()); 152 gl.beginQuery(GL_ANY_SAMPLES_PASSED, query); 153 gl.drawArrays(GL_TRIANGLES, 0, 6); 154 gl.endQuery(GL_ANY_SAMPLES_PASSED); 155 gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &outsideYPassed); 156 log << TestLog::Message << "A fragment was not discarded at (" << size.x()-1 << ", " << size.y() << "). " 157 << "Occlusion query reports it was " << (outsideYPassed > 0 ? "rendered." : "not rendered") << TestLog::EndMessage; 158 159 gl.disableVertexAttribArray(0); 160 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 161 gl.bindVertexArray(0); 162 gl.deleteBuffers(1, &vertexBuffer); 163 gl.deleteVertexArrays(1, &vertexArray); 164 } 165 166 gl.deleteQueries(1, &query); 167 168 GLU_EXPECT_NO_ERROR(gl.getError(), "Query failed"); 169 170 return insidePassed && !outsideXPassed && !outsideYPassed; 171 } 172 173 bool checkFramebufferRenderable (TestLog& log, const glu::RenderContext& renderCtx, GLuint framebuffer, const IVec2& size) 174 { 175 const glw::Functions& gl = renderCtx.getFunctions(); 176 177 const char* const vertexSource = "#version 310 es\n" 178 "in layout(location = 0) highp vec2 a_position;\n\n" 179 "void main()\n" 180 "{\n" 181 " gl_Position = vec4(a_position, 0.0, 1.0);\n" 182 "}\n"; 183 184 const char* const fragmentSource = "#version 310 es\n" 185 "out layout(location = 0) mediump vec4 f_color;\n\n" 186 "void main()\n" 187 "{\n" 188 " f_color = vec4(1.0, 0.5, 0.25, 1.0);\n" 189 "}\n"; 190 191 const glu::ShaderProgram program (renderCtx, glu::makeVtxFragSources(vertexSource, fragmentSource)); 192 GLuint query = 0; 193 194 if (!program.isOk()) 195 log << program; 196 197 TCU_CHECK(program.isOk()); 198 199 gl.useProgram(program.getProgram()); 200 gl.enable(GL_DEPTH_TEST); 201 gl.depthFunc(GL_ALWAYS); 202 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer); 203 gl.viewport(0, 0, size.x(), size.y()); 204 205 TCU_CHECK(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE); 206 207 log << TestLog::Message << "Rendering full framebuffer quad with color ouput, verifying output presence with occlusion query" << TestLog::EndMessage; 208 209 // Render 210 { 211 const float data[] = 212 { 213 1.0f, 1.0f, 214 1.0f, -1.0f, 215 -1.0f, 1.0f, 216 -1.0f, 1.0f, 217 1.0f, -1.0f, 218 -1.0f, -1.0f, 219 }; 220 221 GLuint vertexArray = 0; 222 GLuint vertexBuffer = 0; 223 224 gl.genQueries(1, &query); 225 gl.genVertexArrays(1, &vertexArray); 226 gl.bindVertexArray(vertexArray); 227 228 gl.genBuffers(1, &vertexBuffer); 229 gl.bindBuffer(GL_ARRAY_BUFFER, vertexBuffer); 230 gl.bufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW); 231 232 gl.enableVertexAttribArray(0); 233 gl.vertexAttribPointer(0, 2, GL_FLOAT, false, 0, DE_NULL); 234 235 gl.beginQuery(GL_ANY_SAMPLES_PASSED, query); 236 gl.drawArrays(GL_TRIANGLES, 0, 6); 237 gl.endQuery(GL_ANY_SAMPLES_PASSED); 238 239 gl.disableVertexAttribArray(0); 240 gl.bindBuffer(GL_ARRAY_BUFFER, 0); 241 gl.bindVertexArray(0); 242 gl.deleteBuffers(1, &vertexBuffer); 243 gl.deleteVertexArrays(1, &vertexArray); 244 } 245 246 // Read 247 { 248 GLuint passed = 0; 249 250 gl.getQueryObjectuiv(query, GL_QUERY_RESULT, &passed); 251 gl.deleteQueries(1, &query); 252 253 GLU_EXPECT_NO_ERROR(gl.getError(), "Query failed"); 254 255 if (passed) 256 log << TestLog::Message << "Query passed" << TestLog::EndMessage; 257 else 258 log << TestLog::Message << "Query did not pass" << TestLog::EndMessage; 259 260 return passed != 0; 261 } 262 } 263 264 class FramebufferCompletenessCase : public tcu::TestCase 265 { 266 public: 267 FramebufferCompletenessCase (tcu::TestContext& testCtx, 268 const glu::RenderContext& renderCtx, 269 const char* name, 270 const char* desc); 271 virtual ~FramebufferCompletenessCase (void) {} 272 virtual IterateResult iterate (void); 273 274 private: 275 const glu::RenderContext& m_renderCtx; 276 tcu::ResultCollector m_results; 277 }; 278 279 FramebufferCompletenessCase::FramebufferCompletenessCase (tcu::TestContext& testCtx, 280 const glu::RenderContext& renderCtx, 281 const char* name, 282 const char* desc) 283 : TestCase (testCtx, name, desc) 284 , m_renderCtx (renderCtx) 285 { 286 } 287 288 FramebufferCompletenessCase::IterateResult FramebufferCompletenessCase::iterate (void) 289 { 290 const glw::Functions& gl = m_renderCtx.getFunctions(); 291 GLuint framebuffer = 0; 292 293 gl.genFramebuffers(1, &framebuffer); 294 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer); 295 296 m_results.check(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, "Framebuffer was incorrectly reported as complete when it had no width, height or attachments"); 297 298 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 16); 299 m_results.check(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, "Framebuffer was incorrectly reported as complete when it only had a width"); 300 301 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 16); 302 m_results.check(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE, "Framebuffer not reported as complete when it had width and height set"); 303 304 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0); 305 m_results.check(gl.checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, "Framebuffer was incorrectly reported as complete when it only had a height"); 306 307 gl.deleteFramebuffers(1, &framebuffer); 308 309 m_results.setTestContextResult(m_testCtx); 310 return STOP; 311 } 312 313 struct FboSpec 314 { 315 int width; 316 int height; 317 int samples; 318 319 FboSpec(int width_, int height_, int samples_) : width(width_), height(height_), samples(samples_){} 320 }; 321 322 class SizeCase : public tcu::TestCase 323 { 324 public: 325 SizeCase (tcu::TestContext& testCtx, 326 const glu::RenderContext& renderCtx, 327 const char* name, 328 const char* desc, 329 const FboSpec& spec); 330 virtual ~SizeCase (void) {} 331 332 virtual IterateResult iterate (void); 333 334 enum 335 { 336 USE_MAXIMUM = -1 337 }; 338 private: 339 int getWidth (void) const; 340 int getHeight (void) const; 341 int getSamples (void) const; 342 343 const glu::RenderContext& m_renderCtx; 344 345 const FboSpec m_spec; 346 }; 347 348 SizeCase::SizeCase (tcu::TestContext& testCtx, 349 const glu::RenderContext& renderCtx, 350 const char* name, 351 const char* desc, 352 const FboSpec& spec) 353 : TestCase (testCtx, name, desc) 354 , m_renderCtx (renderCtx) 355 , m_spec (spec) 356 { 357 } 358 359 SizeCase::IterateResult SizeCase::iterate (void) 360 { 361 const glw::Functions& gl = m_renderCtx.getFunctions(); 362 TestLog& log = m_testCtx.getLog(); 363 GLuint framebuffer = 0; 364 const int width = getWidth(); 365 const int height = getHeight(); 366 const int samples = getSamples(); 367 368 gl.genFramebuffers(1, &framebuffer); 369 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer); 370 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, width); 371 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, height); 372 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_SAMPLES, samples); 373 374 log << TestLog::Message << "Verifying " << width << "x" << height << " framebuffer with " << samples << "x multisampling" << TestLog::EndMessage; 375 376 if(checkFramebufferRenderable(log, m_renderCtx, framebuffer, IVec2(width, height)) && checkFramebufferSize(log, m_renderCtx, framebuffer, IVec2(width, height))) 377 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 378 else 379 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Framebuffer did not behave as expected"); 380 381 gl.deleteFramebuffers(1, &framebuffer); 382 383 return STOP; 384 } 385 386 int SizeCase::getWidth (void) const 387 { 388 if (m_spec.width != USE_MAXIMUM) 389 return m_spec.width; 390 else 391 { 392 const glw::Functions& gl = m_renderCtx.getFunctions(); 393 GLint width = 0; 394 395 gl.getIntegerv(GL_MAX_FRAMEBUFFER_WIDTH, &width); 396 397 return width; 398 } 399 } 400 401 int SizeCase::getHeight (void) const 402 { 403 if (m_spec.height != USE_MAXIMUM) 404 return m_spec.height; 405 else 406 { 407 const glw::Functions& gl = m_renderCtx.getFunctions(); 408 GLint height = 0; 409 410 gl.getIntegerv(GL_MAX_FRAMEBUFFER_HEIGHT, &height); 411 412 return height; 413 } 414 } 415 416 int SizeCase::getSamples (void) const 417 { 418 if (m_spec.samples != USE_MAXIMUM) 419 return m_spec.samples; 420 else 421 { 422 const glw::Functions& gl = m_renderCtx.getFunctions(); 423 GLint samples = 0; 424 425 gl.getIntegerv(GL_MAX_FRAMEBUFFER_SAMPLES, &samples); 426 427 return samples; 428 } 429 } 430 431 class AttachmentInteractionCase : public tcu::TestCase 432 { 433 public: 434 AttachmentInteractionCase (tcu::TestContext& testCtx, 435 const glu::RenderContext& renderCtx, 436 const char* name, 437 const char* desc, 438 const FboSpec& defaultSpec, 439 const FboSpec& attachmentSpec); 440 virtual ~AttachmentInteractionCase (void) {} 441 442 virtual IterateResult iterate (void); 443 444 private: 445 const glu::RenderContext& m_renderCtx; 446 const FboSpec m_defaultSpec; 447 const FboSpec m_attachmentSpec; 448 }; 449 450 AttachmentInteractionCase::AttachmentInteractionCase (tcu::TestContext& testCtx, 451 const glu::RenderContext& renderCtx, 452 const char* name, 453 const char* desc, 454 const FboSpec& defaultSpec, 455 const FboSpec& attachmentSpec) 456 : TestCase (testCtx, name, desc) 457 , m_renderCtx (renderCtx) 458 , m_defaultSpec (defaultSpec) 459 , m_attachmentSpec (attachmentSpec) 460 { 461 } 462 463 AttachmentInteractionCase::IterateResult AttachmentInteractionCase::iterate (void) 464 { 465 const glw::Functions& gl = m_renderCtx.getFunctions(); 466 TestLog& log = m_testCtx.getLog(); 467 GLuint framebuffer = 0; 468 GLuint renderbuffer= 0; 469 470 gl.genFramebuffers(1, &framebuffer); 471 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer); 472 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, m_defaultSpec.width); 473 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, m_defaultSpec.height); 474 gl.framebufferParameteri(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_SAMPLES, m_defaultSpec.samples); 475 476 gl.genRenderbuffers(1, &renderbuffer); 477 gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer); 478 gl.renderbufferStorageMultisample(GL_RENDERBUFFER, m_attachmentSpec.samples, GL_RGBA8, m_attachmentSpec.width, m_attachmentSpec.height); 479 gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer); 480 481 log << TestLog::Message << "Verifying " << m_attachmentSpec.width << "x" << m_attachmentSpec.height << " framebuffer with " << m_attachmentSpec.samples << "x multisampling" 482 << " and defaults set to " << m_defaultSpec.width << "x" << m_defaultSpec.height << " with " << m_defaultSpec.samples << "x multisampling" << TestLog::EndMessage; 483 484 if(checkFramebufferRenderable(log, m_renderCtx, framebuffer, IVec2(m_attachmentSpec.width, m_attachmentSpec.height)) 485 && checkFramebufferSize(log, m_renderCtx, framebuffer, IVec2(m_attachmentSpec.width, m_attachmentSpec.height))) 486 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 487 else 488 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Framebuffer did not behave as expected"); 489 490 gl.deleteRenderbuffers(1, &renderbuffer); 491 gl.deleteFramebuffers(1, &framebuffer); 492 493 return STOP; 494 } 495 496 } // Anonymous 497 498 tcu::TestCaseGroup* createFboNoAttachmentTests(Context& context) 499 { 500 const glu::RenderContext& renderCtx = context.getRenderContext(); 501 tcu::TestContext& testCtx = context.getTestContext(); 502 503 const int maxWidth = 2048; // MAX_FRAMEBUFFER_WIDTH in ES 3.1 504 const int maxHeight = 2048; // MAX_FRAMEBUFFER_HEIGHT in ES 3.1 505 const int maxSamples = 4; 506 507 tcu::TestCaseGroup* const root = new tcu::TestCaseGroup(testCtx, "no_attachments", "Framebuffer without attachments"); 508 509 // Size 510 { 511 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "size", "Basic functionality tests with varying default size"); 512 513 root->addChild(group); 514 515 for (int width = 16; width <= maxWidth; width *= 4) 516 { 517 for (int height = 16; height <= maxHeight; height *= 4) 518 { 519 const FboSpec spec (width, height, 0); 520 stringstream name; 521 522 name << width << "x" << height; 523 524 group->addChild(new SizeCase(testCtx, renderCtx, name.str().c_str(), name.str().c_str(), spec)); 525 } 526 } 527 } 528 529 // NPOT size 530 { 531 const FboSpec specs[] = 532 { 533 // Square 534 FboSpec(1, 1, 0), 535 FboSpec(3, 3, 0), 536 FboSpec(15, 15, 0), 537 FboSpec(17, 17, 0), 538 FboSpec(31, 31, 0), 539 FboSpec(33, 33, 0), 540 FboSpec(63, 63, 0), 541 FboSpec(65, 65, 0), 542 FboSpec(127, 127, 0), 543 FboSpec(129, 129, 0), 544 FboSpec(255, 255, 0), 545 FboSpec(257, 257, 0), 546 FboSpec(511, 511, 0), 547 FboSpec(513, 513, 0), 548 FboSpec(1023, 1023, 0), 549 FboSpec(1025, 1025, 0), 550 FboSpec(2047, 2047, 0), 551 552 // Non-square 553 FboSpec(15, 511, 0), 554 FboSpec(127, 15, 0), 555 FboSpec(129, 127, 0), 556 FboSpec(511, 127, 0), 557 FboSpec(2047, 1025, 0), 558 }; 559 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "npot_size", "Basic functionality with Non-power-of-two size"); 560 561 root->addChild(group); 562 563 for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(specs); caseNdx++) 564 { 565 const FboSpec& spec = specs[caseNdx]; 566 stringstream name; 567 568 name << spec.width << "x" << spec.height; 569 570 group->addChild(new SizeCase(testCtx, renderCtx, name.str().c_str(), name.str().c_str(), spec)); 571 } 572 } 573 574 // Multisample 575 { 576 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "multisample", "Basic functionality with multisampled fbo"); 577 578 root->addChild(group); 579 580 for (int samples = 0; samples <= maxSamples; samples++) 581 { 582 const FboSpec spec (128, 128, samples); 583 stringstream name; 584 585 name << "samples" << samples; 586 587 group->addChild(new SizeCase(testCtx, renderCtx, name.str().c_str(), name.str().c_str(), spec)); 588 } 589 } 590 591 // Randomized 592 { 593 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "random", "Randomized size & multisampling"); 594 de::Random rng (0xF0E1E2D3 ^ testCtx.getCommandLine().getBaseSeed()); 595 596 root->addChild(group); 597 598 for (int caseNdx = 0; caseNdx < 16; caseNdx++) 599 { 600 const int width = rng.getInt(1, maxWidth); 601 const int height = rng.getInt(1, maxHeight); 602 const int samples = rng.getInt(0, maxSamples); 603 const FboSpec spec (width, height, samples); 604 const string name = de::toString(caseNdx); 605 606 group->addChild(new SizeCase(testCtx, renderCtx, name.c_str(), name.c_str(), spec)); 607 } 608 } 609 610 // Normal fbo with defaults set 611 { 612 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "interaction", "Interaction of default parameters with normal fbo"); 613 614 root->addChild(group); 615 616 const FboSpec specs[][2] = 617 { 618 { FboSpec(256, 256, 0), FboSpec(128, 128, 1) }, 619 { FboSpec(256, 256, 1), FboSpec(128, 128, 0) }, 620 { FboSpec(256, 256, 0), FboSpec(512, 512, 2) }, 621 { FboSpec(256, 256, 2), FboSpec(128, 512, 0) }, 622 { FboSpec(127, 127, 0), FboSpec(129, 129, 0) }, 623 { FboSpec(17, 512, 4), FboSpec(16, 16, 2) }, 624 { FboSpec(2048, 2048, 4), FboSpec(1, 1, 0) }, 625 { FboSpec(1, 1, 0), FboSpec(2048, 2048, 4) }, 626 }; 627 628 for (int specNdx = 0; specNdx < DE_LENGTH_OF_ARRAY(specs); specNdx++) 629 { 630 const FboSpec& baseSpec = specs[specNdx][0]; 631 const FboSpec& altSpec = specs[specNdx][1]; 632 stringstream baseSpecName, altSpecName; 633 634 baseSpecName << baseSpec.width << "x" << baseSpec.height << "ms" << baseSpec.samples; 635 altSpecName << altSpec.width << "x" << altSpec.height << "ms" << altSpec.samples; 636 637 { 638 const string name = baseSpecName.str() + "_default_" + altSpecName.str(); 639 640 group->addChild(new AttachmentInteractionCase(testCtx, renderCtx, name.c_str(), name.c_str(), altSpec, baseSpec)); 641 } 642 } 643 } 644 645 // Maximums 646 { 647 tcu::TestCaseGroup* const group = new tcu::TestCaseGroup(testCtx, "maximums", "Maximum dimensions"); 648 649 root->addChild(group); 650 group->addChild(new SizeCase(testCtx, renderCtx, "width", "Maximum width", FboSpec(SizeCase::USE_MAXIMUM, 128, 0))); 651 group->addChild(new SizeCase(testCtx, renderCtx, "height", "Maximum height", FboSpec(128, SizeCase::USE_MAXIMUM, 0))); 652 group->addChild(new SizeCase(testCtx, renderCtx, "size", "Maximum size", FboSpec(SizeCase::USE_MAXIMUM, SizeCase::USE_MAXIMUM, 0))); 653 group->addChild(new SizeCase(testCtx, renderCtx, "samples", "Maximum samples", FboSpec(128, 128, SizeCase::USE_MAXIMUM))); 654 group->addChild(new SizeCase(testCtx, renderCtx, "all", "Maximum size & samples", FboSpec(SizeCase::USE_MAXIMUM, SizeCase::USE_MAXIMUM, SizeCase::USE_MAXIMUM))); 655 } 656 657 return root; 658 } 659 660 tcu::TestCaseGroup* createFboNoAttachmentCompletenessTests(Context& context) 661 { 662 TestCaseGroup* const group = new TestCaseGroup(context, "completeness", "Completeness tests"); 663 664 group->addChild(new FramebufferCompletenessCase(context.getTestContext(), context.getRenderContext(), "no_attachments", "No attachments completeness")); 665 666 return group; 667 } 668 669 } // Functional 670 } // gles31 671 } // deqp 672