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