glsFboCompletenessTests.cpp revision b5c60b02e542a61a2b658272034c830f92b4c766
1/*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL (ES) 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 completeness tests. 22 *//*--------------------------------------------------------------------*/ 23 24#include "glsFboCompletenessTests.hpp" 25 26#include "gluStrUtil.hpp" 27#include "gluObjectWrapper.hpp" 28#include "deStringUtil.hpp" 29 30#include <cctype> 31#include <iterator> 32#include <algorithm> 33 34using namespace glw; 35using glu::RenderContext; 36using glu::getFramebufferStatusName; 37using glu::getPixelFormatName; 38using glu::getTypeName; 39using glu::getErrorName; 40using glu::Framebuffer; 41using tcu::TestCase; 42using tcu::TestCaseGroup; 43using tcu::TestLog; 44using tcu::MessageBuilder; 45using tcu::TestNode; 46using std::string; 47using de::toString; 48using de::toLower; 49using namespace deqp::gls::FboUtil; 50using namespace deqp::gls::FboUtil::config; 51typedef TestCase::IterateResult IterateResult; 52 53namespace deqp 54{ 55namespace gls 56{ 57namespace fboc 58{ 59 60namespace details 61{ 62 63// The following extensions are applicable both to ES2 and ES3. 64 65// GL_OES_depth_texture 66static const FormatKey s_oesDepthTextureFormats[] = 67{ 68 GLS_UNSIZED_FORMATKEY(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT), 69 GLS_UNSIZED_FORMATKEY(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT), 70}; 71 72// GL_OES_packed_depth_stencil 73static const FormatKey s_oesPackedDepthStencilSizedFormats[] = 74{ 75 GL_DEPTH24_STENCIL8, 76}; 77 78static const FormatKey s_oesPackedDepthStencilTexFormats[] = 79{ 80 GLS_UNSIZED_FORMATKEY(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8), 81}; 82 83// GL_OES_required_internalformat 84static const FormatKey s_oesRequiredInternalFormatColorFormats[] = 85{ 86 // Same as ES2 RBO formats, plus RGBA8 (even without OES_rgb8_rgba8) 87 GL_RGB5_A1, GL_RGBA8, GL_RGBA4, GL_RGB565 88}; 89 90static const FormatKey s_oesRequiredInternalFormatDepthFormats[] = 91{ 92 GL_DEPTH_COMPONENT16, 93}; 94 95// GL_EXT_color_buffer_half_float 96static const FormatKey s_extColorBufferHalfFloatFormats[] = 97{ 98 GL_RGBA16F, GL_RGB16F, GL_RG16F, GL_R16F, 99}; 100 101static const FormatKey s_oesDepth24SizedFormats[] = 102{ 103 GL_DEPTH_COMPONENT24 104}; 105 106static const FormatKey s_oesDepth32SizedFormats[] = 107{ 108 GL_DEPTH_COMPONENT32 109}; 110 111static const FormatKey s_oesRgb8Rgba8RboFormats[] = 112{ 113 GL_RGB8, 114 GL_RGBA8, 115}; 116 117static const FormatKey s_oesRequiredInternalFormatRgb8ColorFormat[] = 118{ 119 GL_RGB8, 120}; 121 122static const FormatKey s_extTextureType2101010RevFormats[] = 123{ 124 GLS_UNSIZED_FORMATKEY(GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV), 125 GLS_UNSIZED_FORMATKEY(GL_RGB, GL_UNSIGNED_INT_2_10_10_10_REV), 126}; 127 128static const FormatKey s_oesRequiredInternalFormat10bitColorFormats[] = 129{ 130 GL_RGB10_A2, GL_RGB10, 131}; 132 133static const FormatKey s_extTextureRgRboFormats[] = 134{ 135 GL_R8, GL_RG8, 136}; 137 138static const FormatKey s_extTextureRgTexFormats[] = 139{ 140 GLS_UNSIZED_FORMATKEY(GL_RED, GL_UNSIGNED_BYTE), 141 GLS_UNSIZED_FORMATKEY(GL_RG, GL_UNSIGNED_BYTE), 142}; 143 144static const FormatKey s_extTextureRgFloatTexFormats[] = 145{ 146 GLS_UNSIZED_FORMATKEY(GL_RED, GL_FLOAT), 147 GLS_UNSIZED_FORMATKEY(GL_RG, GL_FLOAT), 148}; 149 150static const FormatKey s_extTextureRgHalfFloatTexFormats[] = 151{ 152 GLS_UNSIZED_FORMATKEY(GL_RED, GL_HALF_FLOAT_OES), 153 GLS_UNSIZED_FORMATKEY(GL_RG, GL_HALF_FLOAT_OES), 154}; 155 156static const FormatKey s_nvPackedFloatRboFormats[] = 157{ 158 GL_R11F_G11F_B10F, 159}; 160 161static const FormatKey s_nvPackedFloatTexFormats[] = 162{ 163 GLS_UNSIZED_FORMATKEY(GL_RGB, GL_UNSIGNED_INT_10F_11F_11F_REV), 164}; 165 166static const FormatKey s_extSrgbRboFormats[] = 167{ 168 GL_SRGB8_ALPHA8, 169}; 170 171static const FormatKey s_extSrgbRenderableTexFormats[] = 172{ 173 GLS_UNSIZED_FORMATKEY(GL_SRGB_ALPHA, GL_UNSIGNED_BYTE), 174}; 175 176static const FormatKey s_extSrgbNonRenderableTexFormats[] = 177{ 178 GLS_UNSIZED_FORMATKEY(GL_SRGB, GL_UNSIGNED_BYTE), 179 GL_SRGB8, 180}; 181 182static const FormatKey s_nvSrgbFormatsRboFormats[] = 183{ 184 GL_SRGB8, 185}; 186 187static const FormatKey s_nvSrgbFormatsTextureFormats[] = 188{ 189 GL_SRGB8, 190 191 // The extension does not actually require any unsized format 192 // to be renderable. However, the renderablility of unsized 193 // SRGB,UBYTE internalformat-type pair is implied. 194 GLS_UNSIZED_FORMATKEY(GL_SRGB, GL_UNSIGNED_BYTE), 195}; 196 197static const FormatKey s_oesRgb8Rgba8TexFormats[] = 198{ 199 GLS_UNSIZED_FORMATKEY(GL_RGB, GL_UNSIGNED_BYTE), 200 GLS_UNSIZED_FORMATKEY(GL_RGBA, GL_UNSIGNED_BYTE), 201}; 202 203static const FormatKey s_extTextureSRGBR8Formats[] = 204{ 205 GL_SR8_EXT, 206}; 207 208static const FormatKey s_extTextureSRGBRG8Formats[] = 209{ 210 GL_SRG8_EXT, 211}; 212 213static const FormatExtEntry s_esExtFormats[] = 214{ 215 { 216 "GL_OES_depth_texture", 217 REQUIRED_RENDERABLE | DEPTH_RENDERABLE | TEXTURE_VALID, 218 GLS_ARRAY_RANGE(s_oesDepthTextureFormats), 219 }, 220 { 221 "GL_OES_packed_depth_stencil", 222 REQUIRED_RENDERABLE | DEPTH_RENDERABLE | STENCIL_RENDERABLE | RENDERBUFFER_VALID, 223 GLS_ARRAY_RANGE(s_oesPackedDepthStencilSizedFormats) 224 }, 225 { 226 "GL_OES_packed_depth_stencil GL_OES_required_internalformat", 227 TEXTURE_VALID, 228 GLS_ARRAY_RANGE(s_oesPackedDepthStencilSizedFormats) 229 }, 230 { 231 "GL_OES_packed_depth_stencil", 232 DEPTH_RENDERABLE | STENCIL_RENDERABLE | TEXTURE_VALID, 233 GLS_ARRAY_RANGE(s_oesPackedDepthStencilTexFormats) 234 }, 235 // \todo [2013-12-10 lauri] Find out if OES_texture_half_float is really a 236 // requirement on ES3 also. Or is color_buffer_half_float applicatble at 237 // all on ES3, since there's also EXT_color_buffer_float? 238 { 239 "GL_OES_texture_half_float GL_EXT_color_buffer_half_float", 240 REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID, 241 GLS_ARRAY_RANGE(s_extColorBufferHalfFloatFormats) 242 }, 243 244 // OES_required_internalformat doesn't actually specify that these are renderable, 245 // since it was written against ES 1.1. 246 { 247 "GL_OES_required_internalformat", 248 // Allow but don't require RGBA8 to be color-renderable if 249 // OES_rgb8_rgba8 is not present. 250 COLOR_RENDERABLE | TEXTURE_VALID, 251 GLS_ARRAY_RANGE(s_oesRequiredInternalFormatColorFormats) 252 }, 253 { 254 "GL_OES_required_internalformat", 255 DEPTH_RENDERABLE | TEXTURE_VALID, 256 GLS_ARRAY_RANGE(s_oesRequiredInternalFormatDepthFormats) 257 }, 258 { 259 "GL_EXT_texture_rg", 260 REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID, 261 GLS_ARRAY_RANGE(s_extTextureRgRboFormats) 262 }, 263 // These are not specified to be color-renderable, but the wording is 264 // exactly as ambiguous as the wording in the ES2 spec. 265 { 266 "GL_EXT_texture_rg", 267 COLOR_RENDERABLE | TEXTURE_VALID, 268 GLS_ARRAY_RANGE(s_extTextureRgTexFormats) 269 }, 270 { 271 "GL_EXT_texture_rg GL_OES_texture_float", 272 COLOR_RENDERABLE | TEXTURE_VALID, 273 GLS_ARRAY_RANGE(s_extTextureRgFloatTexFormats) 274 }, 275 { 276 "GL_EXT_texture_rg GL_OES_texture_half_float", 277 COLOR_RENDERABLE | TEXTURE_VALID, 278 GLS_ARRAY_RANGE(s_extTextureRgHalfFloatTexFormats) 279 }, 280 281 { 282 "GL_NV_packed_float", 283 COLOR_RENDERABLE | TEXTURE_VALID, 284 GLS_ARRAY_RANGE(s_nvPackedFloatTexFormats) 285 }, 286 { 287 "GL_NV_packed_float GL_EXT_color_buffer_half_float", 288 REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID, 289 GLS_ARRAY_RANGE(s_nvPackedFloatRboFormats) 290 }, 291 292 // Some Tegra drivers report GL_EXT_packed_float even for ES. Treat it as 293 // a synonym for the NV_ version. 294 { 295 "GL_EXT_packed_float", 296 COLOR_RENDERABLE | TEXTURE_VALID, 297 GLS_ARRAY_RANGE(s_nvPackedFloatTexFormats) 298 }, 299 { 300 "GL_EXT_packed_float GL_EXT_color_buffer_half_float", 301 REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID, 302 GLS_ARRAY_RANGE(s_nvPackedFloatRboFormats) 303 }, 304 305 { 306 "GL_EXT_sRGB", 307 COLOR_RENDERABLE | TEXTURE_VALID, 308 GLS_ARRAY_RANGE(s_extSrgbRenderableTexFormats) 309 }, 310 { 311 "GL_EXT_sRGB", 312 TEXTURE_VALID, 313 GLS_ARRAY_RANGE(s_extSrgbNonRenderableTexFormats) 314 }, 315 { 316 "GL_EXT_sRGB", 317 REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID, 318 GLS_ARRAY_RANGE(s_extSrgbRboFormats) 319 }, 320 { 321 "GL_NV_sRGB_formats", 322 REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID, 323 GLS_ARRAY_RANGE(s_nvSrgbFormatsRboFormats) 324 }, 325 { 326 "GL_NV_sRGB_formats", 327 REQUIRED_RENDERABLE | COLOR_RENDERABLE | TEXTURE_VALID, 328 GLS_ARRAY_RANGE(s_nvSrgbFormatsTextureFormats) 329 }, 330 331 // In Khronos bug 7333 discussion, the consensus is that these texture 332 // formats, at least, should be color-renderable. Still, that cannot be 333 // found in any extension specs, so only allow it, not require it. 334 { 335 "GL_OES_rgb8_rgba8", 336 COLOR_RENDERABLE | TEXTURE_VALID, 337 GLS_ARRAY_RANGE(s_oesRgb8Rgba8TexFormats) 338 }, 339 { 340 "GL_OES_rgb8_rgba8", 341 REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID, 342 GLS_ARRAY_RANGE(s_oesRgb8Rgba8RboFormats) 343 }, 344 { 345 "GL_OES_rgb8_rgba8 GL_OES_required_internalformat", 346 TEXTURE_VALID, 347 GLS_ARRAY_RANGE(s_oesRequiredInternalFormatRgb8ColorFormat) 348 }, 349 350 // The depth-renderability of the depth RBO formats is not explicitly 351 // spelled out, but all renderbuffer formats are meant to be renderable. 352 { 353 "GL_OES_depth24", 354 REQUIRED_RENDERABLE | DEPTH_RENDERABLE | RENDERBUFFER_VALID, 355 GLS_ARRAY_RANGE(s_oesDepth24SizedFormats) 356 }, 357 { 358 "GL_OES_depth24 GL_OES_required_internalformat GL_OES_depth_texture", 359 TEXTURE_VALID, 360 GLS_ARRAY_RANGE(s_oesDepth24SizedFormats) 361 }, 362 363 { 364 "GL_OES_depth32", 365 REQUIRED_RENDERABLE | DEPTH_RENDERABLE | RENDERBUFFER_VALID, 366 GLS_ARRAY_RANGE(s_oesDepth32SizedFormats) 367 }, 368 { 369 "GL_OES_depth32 GL_OES_required_internalformat GL_OES_depth_texture", 370 TEXTURE_VALID, 371 GLS_ARRAY_RANGE(s_oesDepth32SizedFormats) 372 }, 373 374 { 375 "GL_EXT_texture_type_2_10_10_10_REV", 376 TEXTURE_VALID, // explicitly unrenderable 377 GLS_ARRAY_RANGE(s_extTextureType2101010RevFormats) 378 }, 379 { 380 "GL_EXT_texture_type_2_10_10_10_REV GL_OES_required_internalformat", 381 TEXTURE_VALID, // explicitly unrenderable 382 GLS_ARRAY_RANGE(s_oesRequiredInternalFormat10bitColorFormats) 383 }, 384 385 { 386 "GL_EXT_texture_sRGB_R8", 387 TEXTURE_VALID, 388 GLS_ARRAY_RANGE(s_extTextureSRGBR8Formats) 389 }, 390 { 391 "GL_EXT_texture_sRGB_RG8", 392 TEXTURE_VALID, 393 GLS_ARRAY_RANGE(s_extTextureSRGBRG8Formats) 394 }, 395}; 396 397Context::Context (TestContext& testCtx, 398 RenderContext& renderCtx, 399 CheckerFactory& factory) 400 : m_testCtx (testCtx) 401 , m_renderCtx (renderCtx) 402 , m_verifier (m_ctxFormats, factory) 403 , m_haveMultiColorAtts (false) 404{ 405 FormatExtEntries extRange = GLS_ARRAY_RANGE(s_esExtFormats); 406 addExtFormats(extRange); 407} 408 409void Context::addFormats (FormatEntries fmtRange) 410{ 411 FboUtil::addFormats(m_coreFormats, fmtRange); 412 FboUtil::addFormats(m_ctxFormats, fmtRange); 413 FboUtil::addFormats(m_allFormats, fmtRange); 414} 415 416void Context::addExtFormats (FormatExtEntries extRange) 417{ 418 FboUtil::addExtFormats(m_ctxFormats, extRange, &m_renderCtx); 419 FboUtil::addExtFormats(m_allFormats, extRange, DE_NULL); 420} 421 422void TestBase::pass (void) 423{ 424 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); 425} 426 427void TestBase::qualityWarning (const char* msg) 428{ 429 m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, msg); 430} 431 432void TestBase::fail (const char* msg) 433{ 434 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, msg); 435} 436 437const glw::Functions& gl (const TestBase& test) 438{ 439 return test.getContext().getRenderContext().getFunctions(); 440} 441 442static bool isFormatFeatureSupported (const FormatDB& db, const ImageFormat& format, FormatFlags feature) 443{ 444 return db.isKnownFormat(format) && ((db.getFormatInfo(format) & feature) == feature); 445} 446 447static void logAffectingExtensions (const char* prefix, const FormatDB& db, const ImageFormat& format, FormatFlags feature, tcu::MessageBuilder& msg) 448{ 449 const std::set<std::set<std::string> > rows = db.getFormatFeatureExtensions(format, feature); 450 451 for (std::set<std::set<std::string> >::const_iterator rowIt = rows.begin(); rowIt != rows.end(); ++rowIt) 452 { 453 const std::set<std::string>& requiredExtensions = *rowIt; 454 std::set<std::string>::const_iterator it = requiredExtensions.begin(); 455 std::string extName; 456 457 msg << prefix; 458 459 extName = *it++; 460 while (it != requiredExtensions.end()) 461 { 462 msg << extName; 463 extName = *it++; 464 msg << (it == requiredExtensions.end() ? " and " : ", "); 465 } 466 467 msg << extName << '\n'; 468 } 469} 470 471static void logFormatInfo (const config::Framebuffer& fbo, const FormatDB& ctxFormats, const FormatDB& coreFormats, const FormatDB& allFormats, tcu::TestLog& log) 472{ 473 static const struct 474 { 475 const char* name; 476 const FormatFlags flag; 477 } s_renderability[] = 478 { 479 { "color-renderable", COLOR_RENDERABLE }, 480 { "depth-renderable", DEPTH_RENDERABLE }, 481 { "stencil-renderable", STENCIL_RENDERABLE }, 482 }; 483 484 std::set<ImageFormat> formats; 485 486 for (config::TextureMap::const_iterator it = fbo.textures.begin(); it != fbo.textures.end(); ++it) 487 formats.insert(it->second->internalFormat); 488 for (config::RboMap::const_iterator it = fbo.rbos.begin(); it != fbo.rbos.end(); ++it) 489 formats.insert(it->second->internalFormat); 490 491 if (!formats.empty()) 492 { 493 const tcu::ScopedLogSection supersection(log, "Format", "Format info"); 494 495 for (std::set<ImageFormat>::const_iterator it = formats.begin(); it != formats.end(); ++it) 496 { 497 const tcu::ScopedLogSection section(log, "FormatInfo", de::toString(*it)); 498 499 // texture validity 500 if (isFormatFeatureSupported(ctxFormats, *it, TEXTURE_VALID)) 501 { 502 tcu::MessageBuilder msg(&log); 503 msg << "* Valid texture format\n"; 504 505 if (isFormatFeatureSupported(coreFormats, *it, TEXTURE_VALID)) 506 msg << "\t* core feature"; 507 else 508 { 509 msg << "\t* defined in supported extension(s):\n"; 510 logAffectingExtensions("\t\t- ", ctxFormats, *it, TEXTURE_VALID, msg); 511 } 512 513 msg << tcu::TestLog::EndMessage; 514 } 515 else 516 { 517 tcu::MessageBuilder msg(&log); 518 msg << "* Unsupported texture format\n"; 519 520 if (isFormatFeatureSupported(allFormats, *it, TEXTURE_VALID)) 521 { 522 msg << "\t* requires any of the extensions or combinations:\n"; 523 logAffectingExtensions("\t\t- ", allFormats, *it, TEXTURE_VALID, msg); 524 } 525 else 526 msg << "\t* no extension can make this format valid"; 527 528 msg << tcu::TestLog::EndMessage; 529 } 530 531 // RBO validity 532 if (isFormatFeatureSupported(ctxFormats, *it, RENDERBUFFER_VALID)) 533 { 534 tcu::MessageBuilder msg(&log); 535 msg << "* Valid renderbuffer format\n"; 536 537 if (isFormatFeatureSupported(coreFormats, *it, RENDERBUFFER_VALID)) 538 msg << "\t* core feature"; 539 else 540 { 541 msg << "\t* defined in supported extension(s):\n"; 542 logAffectingExtensions("\t\t- ", ctxFormats, *it, RENDERBUFFER_VALID, msg); 543 } 544 545 msg << tcu::TestLog::EndMessage; 546 } 547 else 548 { 549 tcu::MessageBuilder msg(&log); 550 msg << "* Unsupported renderbuffer format\n"; 551 552 if (isFormatFeatureSupported(allFormats, *it, RENDERBUFFER_VALID)) 553 { 554 msg << "\t* requires any of the extensions or combinations:\n"; 555 logAffectingExtensions("\t\t- ", allFormats, *it, RENDERBUFFER_VALID, msg); 556 } 557 else 558 msg << "\t* no extension can make this format valid"; 559 560 msg << tcu::TestLog::EndMessage; 561 } 562 563 // renderability 564 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_renderability); ++ndx) 565 { 566 if (isFormatFeatureSupported(ctxFormats, *it, s_renderability[ndx].flag | REQUIRED_RENDERABLE)) 567 { 568 tcu::MessageBuilder msg(&log); 569 msg << "* Format is " << s_renderability[ndx].name << "\n"; 570 571 if (isFormatFeatureSupported(coreFormats, *it, s_renderability[ndx].flag | REQUIRED_RENDERABLE)) 572 msg << "\t* core feature"; 573 else 574 { 575 msg << "\t* defined in supported extension(s):\n"; 576 logAffectingExtensions("\t\t- ", ctxFormats, *it, s_renderability[ndx].flag | REQUIRED_RENDERABLE, msg); 577 } 578 579 msg << tcu::TestLog::EndMessage; 580 } 581 else if (isFormatFeatureSupported(ctxFormats, *it, s_renderability[ndx].flag)) 582 { 583 tcu::MessageBuilder msg(&log); 584 msg << "* Format is allowed to be " << s_renderability[ndx].name << " but not required\n"; 585 586 if (isFormatFeatureSupported(coreFormats, *it, s_renderability[ndx].flag)) 587 msg << "\t* core feature"; 588 else if (isFormatFeatureSupported(allFormats, *it, s_renderability[ndx].flag)) 589 { 590 msg << "\t* extensions that would make format " << s_renderability[ndx].name << ":\n"; 591 logAffectingExtensions("\t\t- ", allFormats, *it, s_renderability[ndx].flag, msg); 592 } 593 else 594 msg << "\t* no extension can make this format " << s_renderability[ndx].name; 595 596 msg << tcu::TestLog::EndMessage; 597 } 598 else 599 { 600 tcu::MessageBuilder msg(&log); 601 msg << "* Format is NOT " << s_renderability[ndx].name << "\n"; 602 603 if (isFormatFeatureSupported(allFormats, *it, s_renderability[ndx].flag)) 604 { 605 if (isFormatFeatureSupported(allFormats, *it, s_renderability[ndx].flag | REQUIRED_RENDERABLE)) 606 { 607 msg << "\t* extensions that would make format " << s_renderability[ndx].name << ":\n"; 608 logAffectingExtensions("\t\t- ", allFormats, *it, s_renderability[ndx].flag | REQUIRED_RENDERABLE, msg); 609 } 610 else 611 { 612 msg << "\t* extensions that are allowed to make format " << s_renderability[ndx].name << ":\n"; 613 logAffectingExtensions("\t\t- ", allFormats, *it, s_renderability[ndx].flag, msg); 614 } 615 } 616 else 617 msg << "\t* no extension can make this format " << s_renderability[ndx].name; 618 619 msg << tcu::TestLog::EndMessage; 620 } 621 } 622 } 623 } 624} 625 626IterateResult TestBase::iterate (void) 627{ 628 glu::Framebuffer fbo (m_ctx.getRenderContext()); 629 FboBuilder builder (*fbo, GL_FRAMEBUFFER, gl(*this)); 630 const IterateResult ret = build(builder); 631 const ValidStatusCodes reference = m_ctx.getVerifier().validStatusCodes(builder); 632 const GLenum errorCode = builder.getError(); 633 634 logFramebufferConfig(builder, m_testCtx.getLog()); 635 logFormatInfo(builder, m_ctx.getCtxFormats(), m_ctx.getCoreFormats(), m_ctx.getAllFormats(), m_testCtx.getLog()); 636 reference.logRules(m_testCtx.getLog()); 637 reference.logLegalResults(m_testCtx.getLog()); 638 639 // \todo [2013-12-04 lauri] Check if drawing operations succeed. 640 641 if (errorCode != GL_NO_ERROR) 642 { 643 m_testCtx.getLog() 644 << TestLog::Message 645 << "Received " << glu::getErrorStr(errorCode) << " (during FBO initialization)." 646 << TestLog::EndMessage; 647 648 if (reference.isErrorCodeValid(errorCode)) 649 pass(); 650 else if (reference.isErrorCodeRequired(GL_NO_ERROR)) 651 fail(("Expected no error but got " + de::toString(glu::getErrorStr(errorCode))).c_str()); 652 else 653 fail("Got wrong error code"); 654 } 655 else 656 { 657 const GLenum fboStatus = gl(*this).checkFramebufferStatus(GL_FRAMEBUFFER); 658 const bool validStatus = reference.isFBOStatusValid(fboStatus); 659 660 m_testCtx.getLog() 661 << TestLog::Message 662 << "Received " << glu::getFramebufferStatusStr(fboStatus) << "." 663 << TestLog::EndMessage; 664 665 if (!validStatus) 666 { 667 if (fboStatus == GL_FRAMEBUFFER_COMPLETE) 668 fail("Framebuffer checked as complete, expected incomplete"); 669 else if (reference.isFBOStatusRequired(GL_FRAMEBUFFER_COMPLETE)) 670 fail("Framebuffer checked is incomplete, expected complete"); 671 else 672 // An incomplete status is allowed, but not _this_ incomplete status. 673 fail("Framebuffer checked as incomplete, but with wrong status"); 674 } 675 else if (fboStatus != GL_FRAMEBUFFER_COMPLETE && reference.isFBOStatusValid(GL_FRAMEBUFFER_COMPLETE)) 676 qualityWarning("Framebuffer object could have checked as complete but did not."); 677 else 678 pass(); 679 } 680 681 return ret; 682} 683 684IterateResult TestBase::build (FboBuilder& builder) 685{ 686 DE_UNREF(builder); 687 return STOP; 688} 689 690ImageFormat TestBase::getDefaultFormat (GLenum attPoint, GLenum bufType) const 691{ 692 if (bufType == GL_NONE) 693 { 694 return ImageFormat::none(); 695 } 696 697 // Prefer a standard format, if there is one, but if not, use a format 698 // provided by an extension. 699 Formats formats = m_ctx.getCoreFormats().getFormats(formatFlag(attPoint) | 700 formatFlag(bufType)); 701 Formats::const_iterator it = formats.begin(); 702 if (it == formats.end()) 703 { 704 formats = m_ctx.getCtxFormats().getFormats(formatFlag(attPoint) | 705 formatFlag(bufType)); 706 it = formats.begin(); 707 } 708 if (it == formats.end()) 709 throw tcu::NotSupportedError("Unsupported attachment kind for attachment point", 710 "", __FILE__, __LINE__); 711 return *it; 712}; 713 714Image* makeImage (GLenum bufType, ImageFormat format, 715 GLsizei width, GLsizei height, FboBuilder& builder) 716{ 717 Image* image = DE_NULL; 718 switch (bufType) 719 { 720 case GL_NONE: 721 return DE_NULL; 722 case GL_RENDERBUFFER: 723 image = &builder.makeConfig<Renderbuffer>(); 724 break; 725 case GL_TEXTURE: 726 image = &builder.makeConfig<Texture2D>(); 727 break; 728 default: 729 DE_ASSERT(!"Impossible case"); 730 } 731 image->internalFormat = format; 732 image->width = width; 733 image->height = height; 734 return image; 735} 736 737Attachment* makeAttachment (GLenum bufType, ImageFormat format, 738 GLsizei width, GLsizei height, FboBuilder& builder) 739{ 740 Image* const imgCfg = makeImage (bufType, format, width, height, builder); 741 Attachment* att = DE_NULL; 742 GLuint img = 0; 743 744 if (Renderbuffer* rboCfg = dynamic_cast<Renderbuffer*>(imgCfg)) 745 { 746 img = builder.glCreateRbo(*rboCfg); 747 att = &builder.makeConfig<RenderbufferAttachment>(); 748 } 749 else if (Texture2D* texCfg = dynamic_cast<Texture2D*>(imgCfg)) 750 { 751 img = builder.glCreateTexture(*texCfg); 752 TextureFlatAttachment& texAtt = builder.makeConfig<TextureFlatAttachment>(); 753 texAtt.texTarget = GL_TEXTURE_2D; 754 att = &texAtt; 755 } 756 else 757 { 758 DE_ASSERT(imgCfg == DE_NULL); 759 return DE_NULL; 760 } 761 att->imageName = img; 762 return att; 763} 764 765void TestBase::attachTargetToNew (GLenum target, GLenum bufType, ImageFormat format, 766 GLsizei width, GLsizei height, FboBuilder& builder) 767{ 768 ImageFormat imgFmt = format; 769 if (imgFmt.format == GL_NONE) 770 imgFmt = getDefaultFormat(target, bufType); 771 772 const Attachment* const att = makeAttachment(bufType, imgFmt, width, height, builder); 773 builder.glAttach(target, att); 774} 775 776static string formatName (ImageFormat format) 777{ 778 const string s = getPixelFormatName(format.format); 779 const string fmtStr = toLower(s.substr(3)); 780 781 if (format.unsizedType != GL_NONE) 782 { 783 const string typeStr = getTypeName(format.unsizedType); 784 return fmtStr + "_" + toLower(typeStr.substr(3)); 785 } 786 787 return fmtStr; 788} 789 790static string formatDesc (ImageFormat format) 791{ 792 const string fmtStr = getPixelFormatName(format.format); 793 794 if (format.unsizedType != GL_NONE) 795 { 796 const string typeStr = getTypeName(format.unsizedType); 797 return fmtStr + " with type " + typeStr; 798 } 799 800 return fmtStr; 801} 802 803struct RenderableParams 804{ 805 GLenum attPoint; 806 GLenum bufType; 807 ImageFormat format; 808 static string getName (const RenderableParams& params) 809 { 810 return formatName(params.format); 811 } 812 static string getDescription (const RenderableParams& params) 813 { 814 return formatDesc(params.format); 815 } 816}; 817 818class RenderableTest : public ParamTest<RenderableParams> 819{ 820public: 821 RenderableTest (Context& group, const Params& params) 822 : ParamTest<RenderableParams> (group, params) {} 823 IterateResult build (FboBuilder& builder); 824}; 825 826IterateResult RenderableTest::build (FboBuilder& builder) 827{ 828 attachTargetToNew(m_params.attPoint, m_params.bufType, m_params.format, 64, 64, builder); 829 return STOP; 830} 831 832string attTypeName (GLenum bufType) 833{ 834 switch (bufType) 835 { 836 case GL_NONE: 837 return "none"; 838 case GL_RENDERBUFFER: 839 return "rbo"; 840 case GL_TEXTURE: 841 return "tex"; 842 default: 843 DE_ASSERT(!"Impossible case"); 844 } 845 return ""; // Shut up compiler 846} 847 848struct AttachmentParams 849{ 850 GLenum color0Kind; 851 GLenum colornKind; 852 GLenum depthKind; 853 GLenum stencilKind; 854 855 static string getName (const AttachmentParams& params); 856 static string getDescription (const AttachmentParams& params) 857 { 858 return getName(params); 859 } 860}; 861 862string AttachmentParams::getName (const AttachmentParams& params) 863{ 864 return (attTypeName(params.color0Kind) + "_" + 865 attTypeName(params.colornKind) + "_" + 866 attTypeName(params.depthKind) + "_" + 867 attTypeName(params.stencilKind)); 868} 869 870//! Test for combinations of different kinds of attachments 871class AttachmentTest : public ParamTest<AttachmentParams> 872{ 873public: 874 AttachmentTest (Context& group, Params& params) 875 : ParamTest<AttachmentParams> (group, params) {} 876 877protected: 878 IterateResult build (FboBuilder& builder); 879 void makeDepthAndStencil (FboBuilder& builder); 880}; 881 882 883void AttachmentTest::makeDepthAndStencil (FboBuilder& builder) 884{ 885 if (m_params.stencilKind == m_params.depthKind) 886 { 887 // If there is a common stencil+depth -format, try to use a common 888 // image for both attachments. 889 const FormatFlags flags = 890 DEPTH_RENDERABLE | STENCIL_RENDERABLE | formatFlag(m_params.stencilKind); 891 const Formats& formats = m_ctx.getCoreFormats().getFormats(flags); 892 Formats::const_iterator it = formats.begin(); 893 if (it != formats.end()) 894 { 895 const ImageFormat format = *it; 896 Attachment* att = makeAttachment(m_params.depthKind, format, 64, 64, builder); 897 builder.glAttach(GL_DEPTH_ATTACHMENT, att); 898 builder.glAttach(GL_STENCIL_ATTACHMENT, att); 899 return; 900 } 901 } 902 // Either the kinds were separate, or a suitable format was not found. 903 // Create separate images. 904 attachTargetToNew(GL_STENCIL_ATTACHMENT, m_params.stencilKind, ImageFormat::none(), 905 64, 64, builder); 906 attachTargetToNew(GL_DEPTH_ATTACHMENT, m_params.depthKind, ImageFormat::none(), 907 64, 64, builder); 908} 909 910IterateResult AttachmentTest::build (FboBuilder& builder) 911{ 912 attachTargetToNew(GL_COLOR_ATTACHMENT0, m_params.color0Kind, ImageFormat::none(), 913 64, 64, builder); 914 915 if (m_params.colornKind != GL_NONE) 916 { 917 TCU_CHECK_AND_THROW(NotSupportedError, m_ctx.haveMultiColorAtts(), 918 "Multiple attachments not supported"); 919 GLint maxAttachments = 1; 920 gl(*this).getIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxAttachments); 921 GLU_EXPECT_NO_ERROR( 922 gl(*this).getError(), "Couldn't read GL_MAX_COLOR_ATTACHMENTS"); 923 924 for (int i = 1; i < maxAttachments; i++) 925 { 926 attachTargetToNew(GL_COLOR_ATTACHMENT0 + i, m_params.colornKind, 927 ImageFormat::none(), 64, 64, builder); 928 } 929 } 930 931 makeDepthAndStencil(builder); 932 933 return STOP; 934} 935 936class EmptyImageTest : public TestBase 937{ 938public: 939 EmptyImageTest (Context& group, 940 const char* name, const char* desc) 941 : TestBase (group, name, desc) {} 942 943 IterateResult build (FboBuilder& builder); 944}; 945 946IterateResult EmptyImageTest::build (FboBuilder& builder) 947{ 948 attachTargetToNew(GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, ImageFormat::none(), 949 0, 0, builder); 950 return STOP; 951} 952 953 954class DistinctSizeTest : public TestBase 955{ 956public: 957 DistinctSizeTest (Context& group, 958 const char* name, const char* desc) 959 : TestBase (group, name, desc) {} 960 961 IterateResult build (FboBuilder& builder); 962}; 963 964IterateResult DistinctSizeTest::build (FboBuilder& builder) 965{ 966 attachTargetToNew(GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, ImageFormat::none(), 967 64, 64, builder); 968 attachTargetToNew(GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, ImageFormat::none(), 969 128, 128, builder); 970 return STOP; 971} 972 973TestCaseGroup* Context::createRenderableTests (void) 974{ 975 TestCaseGroup* const renderableTests = new TestCaseGroup( 976 m_testCtx, "renderable", "Tests for support of renderable image formats"); 977 978 TestCaseGroup* const rbRenderableTests = new TestCaseGroup( 979 m_testCtx, "renderbuffer", "Tests for renderbuffer formats"); 980 981 TestCaseGroup* const texRenderableTests = new TestCaseGroup( 982 m_testCtx, "texture", "Tests for texture formats"); 983 984 static const struct AttPoint { 985 GLenum attPoint; 986 const char* name; 987 const char* desc; 988 } attPoints[] = 989 { 990 { GL_COLOR_ATTACHMENT0, "color0", "Tests for color attachments" }, 991 { GL_STENCIL_ATTACHMENT, "stencil", "Tests for stencil attachments" }, 992 { GL_DEPTH_ATTACHMENT, "depth", "Tests for depth attachments" }, 993 }; 994 995 // At each attachment point, iterate through all the possible formats to 996 // detect both false positives and false negatives. 997 const Formats rboFmts = m_allFormats.getFormats(ANY_FORMAT); 998 const Formats texFmts = m_allFormats.getFormats(ANY_FORMAT); 999 1000 for (const AttPoint* it = DE_ARRAY_BEGIN(attPoints); it != DE_ARRAY_END(attPoints); it++) 1001 { 1002 TestCaseGroup* const rbAttTests = new TestCaseGroup(m_testCtx, it->name, it->desc); 1003 TestCaseGroup* const texAttTests = new TestCaseGroup(m_testCtx, it->name, it->desc); 1004 1005 for (Formats::const_iterator it2 = rboFmts.begin(); it2 != rboFmts.end(); it2++) 1006 { 1007 const RenderableParams params = { it->attPoint, GL_RENDERBUFFER, *it2 }; 1008 rbAttTests->addChild(new RenderableTest(*this, params)); 1009 } 1010 rbRenderableTests->addChild(rbAttTests); 1011 1012 for (Formats::const_iterator it2 = texFmts.begin(); it2 != texFmts.end(); it2++) 1013 { 1014 const RenderableParams params = { it->attPoint, GL_TEXTURE, *it2 }; 1015 texAttTests->addChild(new RenderableTest(*this, params)); 1016 } 1017 texRenderableTests->addChild(texAttTests); 1018 } 1019 renderableTests->addChild(rbRenderableTests); 1020 renderableTests->addChild(texRenderableTests); 1021 1022 return renderableTests; 1023} 1024 1025TestCaseGroup* Context::createAttachmentTests (void) 1026{ 1027 TestCaseGroup* const attCombTests = new TestCaseGroup( 1028 m_testCtx, "attachment_combinations", "Tests for attachment combinations"); 1029 1030 static const GLenum s_bufTypes[] = { GL_NONE, GL_RENDERBUFFER, GL_TEXTURE }; 1031 static const Range<GLenum> s_kinds = GLS_ARRAY_RANGE(s_bufTypes); 1032 1033 for (const GLenum* col0 = s_kinds.begin(); col0 != s_kinds.end(); ++col0) 1034 for (const GLenum* coln = s_kinds.begin(); coln != s_kinds.end(); ++coln) 1035 for (const GLenum* dep = s_kinds.begin(); dep != s_kinds.end(); ++dep) 1036 for (const GLenum* stc = s_kinds.begin(); stc != s_kinds.end(); ++stc) 1037 { 1038 AttachmentParams params = { *col0, *coln, *dep, *stc }; 1039 attCombTests->addChild(new AttachmentTest(*this, params)); 1040 } 1041 1042 return attCombTests; 1043} 1044 1045TestCaseGroup* Context::createSizeTests (void) 1046{ 1047 TestCaseGroup* const sizeTests = new TestCaseGroup( 1048 m_testCtx, "size", "Tests for attachment sizes"); 1049 sizeTests->addChild(new EmptyImageTest( 1050 *this, "zero", 1051 "Test for zero-sized image attachment")); 1052 sizeTests->addChild(new DistinctSizeTest( 1053 *this, "distinct", 1054 "Test for attachments with different sizes")); 1055 1056 return sizeTests; 1057} 1058 1059} // details 1060 1061} // fboc 1062} // gls 1063} // deqp 1064