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