1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES 3.0 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 Object Tests. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "es3fFboRenderTest.hpp" 25 #include "sglrContextUtil.hpp" 26 #include "sglrGLContext.hpp" 27 #include "sglrReferenceContext.hpp" 28 #include "es3fFboTestUtil.hpp" 29 #include "tcuSurface.hpp" 30 #include "tcuImageCompare.hpp" 31 #include "tcuTextureUtil.hpp" 32 #include "tcuVectorUtil.hpp" 33 #include "tcuRenderTarget.hpp" 34 #include "gluPixelTransfer.hpp" 35 #include "gluTextureUtil.hpp" 36 #include "gluStrUtil.hpp" 37 #include "deRandom.h" 38 #include "deString.h" 39 #include "glwDefs.hpp" 40 #include "glwEnums.hpp" 41 42 #include <sstream> 43 44 using std::vector; 45 using std::string; 46 using tcu::TestLog; 47 using tcu::Vec2; 48 using tcu::Vec3; 49 using tcu::Vec4; 50 using tcu::IVec2; 51 using tcu::IVec3; 52 using tcu::IVec4; 53 using tcu::RGBA; 54 using tcu::Surface; 55 56 namespace deqp 57 { 58 namespace gles3 59 { 60 namespace Functional 61 { 62 63 using glw::GLenum; 64 using namespace FboTestUtil; 65 66 class FboConfig 67 { 68 public: 69 FboConfig (deUint32 buffers_, deUint32 colorType_, deUint32 colorFormat_, deUint32 depthStencilType_, deUint32 depthStencilFormat_, int width_ = 0, int height_ = 0, int samples_ = 0) 70 : buffers (buffers_) 71 , colorType (colorType_) 72 , colorFormat (colorFormat_) 73 , depthStencilType (depthStencilType_) 74 , depthStencilFormat (depthStencilFormat_) 75 , width (width_) 76 , height (height_) 77 , samples (samples_) 78 { 79 } 80 81 FboConfig (void) 82 : buffers (0) 83 , colorType (GL_NONE) 84 , colorFormat (GL_NONE) 85 , depthStencilType (GL_NONE) 86 , depthStencilFormat (GL_NONE) 87 , width (0) 88 , height (0) 89 , samples (0) 90 { 91 } 92 93 std::string getName (void) const; 94 95 deUint32 buffers; //!< Buffer bit mask (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|...) 96 97 GLenum colorType; //!< GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, GL_RENDERBUFFER 98 GLenum colorFormat; //!< Internal format for color buffer texture or renderbuffer 99 100 GLenum depthStencilType; 101 GLenum depthStencilFormat; 102 103 int width; 104 int height; 105 int samples; 106 }; 107 108 static const char* getTypeName (GLenum type) 109 { 110 switch (type) 111 { 112 case GL_TEXTURE_2D: return "tex2d"; 113 case GL_RENDERBUFFER: return "rbo"; 114 default: 115 TCU_FAIL("Unknown type"); 116 } 117 } 118 119 std::string FboConfig::getName (void) const 120 { 121 std::ostringstream name; 122 123 DE_ASSERT(buffers & GL_COLOR_BUFFER_BIT); 124 name << getTypeName(colorType) << "_" << getFormatName(colorFormat); 125 126 if (buffers & GL_DEPTH_BUFFER_BIT) 127 name << "_depth"; 128 if (buffers & GL_STENCIL_BUFFER_BIT) 129 name << "_stencil"; 130 131 if (buffers & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) 132 name << "_" << getTypeName(depthStencilType) << "_" << getFormatName(depthStencilFormat); 133 134 return name.str(); 135 } 136 137 class Framebuffer 138 { 139 public: 140 Framebuffer (sglr::Context& context, const FboConfig& config, int width, int height, deUint32 fbo = 0, deUint32 colorBuffer = 0, deUint32 depthStencilBuffer = 0); 141 ~Framebuffer (void); 142 143 const FboConfig& getConfig (void) const { return m_config; } 144 deUint32 getFramebuffer (void) const { return m_framebuffer; } 145 deUint32 getColorBuffer (void) const { return m_colorBuffer; } 146 deUint32 getDepthStencilBuffer (void) const { return m_depthStencilBuffer; } 147 148 void checkCompleteness (void); 149 150 private: 151 deUint32 createTex2D (deUint32 name, GLenum format, int width, int height); 152 deUint32 createRbo (deUint32 name, GLenum format, int width, int height); 153 void destroyBuffer (deUint32 name, GLenum type); 154 155 FboConfig m_config; 156 sglr::Context& m_context; 157 deUint32 m_framebuffer; 158 deUint32 m_colorBuffer; 159 deUint32 m_depthStencilBuffer; 160 }; 161 162 static std::vector<std::string> getEnablingExtensions (deUint32 format) 163 { 164 std::vector<std::string> out; 165 166 switch (format) 167 { 168 case GL_RGB16F: 169 out.push_back("GL_EXT_color_buffer_half_float"); 170 break; 171 172 case GL_RGBA16F: 173 case GL_RG16F: 174 case GL_R16F: 175 out.push_back("GL_EXT_color_buffer_half_float"); 176 // Fallthrough 177 178 case GL_RGBA32F: 179 case GL_RGB32F: 180 case GL_R11F_G11F_B10F: 181 case GL_RG32F: 182 case GL_R32F: 183 out.push_back("GL_EXT_color_buffer_float"); 184 break; 185 186 default: 187 break; 188 } 189 190 return out; 191 } 192 193 static bool isExtensionSupported (sglr::Context& context, const char* name) 194 { 195 std::istringstream extensions(context.getString(GL_EXTENSIONS)); 196 std::string extension; 197 198 while (std::getline(extensions, extension, ' ')) 199 { 200 if (extension == name) 201 return true; 202 } 203 204 return false; 205 } 206 207 static bool isAnyExtensionSupported (sglr::Context& context, const std::vector<std::string>& requiredExts) 208 { 209 if (requiredExts.empty()) 210 return true; 211 212 for (std::vector<std::string>::const_iterator iter = requiredExts.begin(); iter != requiredExts.end(); iter++) 213 { 214 const std::string& extension = *iter; 215 216 if (isExtensionSupported(context, extension.c_str())) 217 return true; 218 } 219 220 return false; 221 } 222 223 template<typename T> 224 static std::string join (const std::vector<T>& list, const std::string& sep) 225 { 226 std::ostringstream out; 227 228 for (typename std::vector<T>::const_iterator iter = list.begin(); iter != list.end(); iter++) 229 { 230 if (iter != list.begin()) 231 out << sep; 232 out << *iter; 233 } 234 235 return out.str(); 236 } 237 238 static void checkColorFormatSupport (sglr::Context& context, deUint32 sizedFormat) 239 { 240 const std::vector<std::string> requiredExts = getEnablingExtensions(sizedFormat); 241 242 if (!isAnyExtensionSupported(context, requiredExts)) 243 { 244 std::string errMsg = "Format not supported, requires " 245 + ((requiredExts.size() == 1) ? requiredExts[0] : " one of the following: " + join(requiredExts, ", ")); 246 247 throw tcu::NotSupportedError(errMsg); 248 } 249 } 250 251 Framebuffer::Framebuffer (sglr::Context& context, const FboConfig& config, int width, int height, deUint32 fbo, deUint32 colorBufferName, deUint32 depthStencilBufferName) 252 : m_config (config) 253 , m_context (context) 254 , m_framebuffer (fbo) 255 , m_colorBuffer (0) 256 , m_depthStencilBuffer (0) 257 { 258 // Verify that color format is supported 259 checkColorFormatSupport(context, config.colorFormat); 260 261 if (m_framebuffer == 0) 262 context.genFramebuffers(1, &m_framebuffer); 263 context.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 264 265 if (m_config.buffers & (GL_COLOR_BUFFER_BIT)) 266 { 267 switch (m_config.colorType) 268 { 269 case GL_TEXTURE_2D: 270 m_colorBuffer = createTex2D(colorBufferName, m_config.colorFormat, width, height); 271 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0); 272 break; 273 274 case GL_RENDERBUFFER: 275 m_colorBuffer = createRbo(colorBufferName, m_config.colorFormat, width, height); 276 context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_colorBuffer); 277 break; 278 279 default: 280 TCU_FAIL("Unsupported type"); 281 } 282 } 283 284 if (m_config.buffers & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) 285 { 286 switch (m_config.depthStencilType) 287 { 288 case GL_TEXTURE_2D: m_depthStencilBuffer = createTex2D(depthStencilBufferName, m_config.depthStencilFormat, width, height); break; 289 case GL_RENDERBUFFER: m_depthStencilBuffer = createRbo(depthStencilBufferName, m_config.depthStencilFormat, width, height); break; 290 default: 291 TCU_FAIL("Unsupported type"); 292 } 293 } 294 295 for (int ndx = 0; ndx < 2; ndx++) 296 { 297 deUint32 bit = ndx ? GL_STENCIL_BUFFER_BIT : GL_DEPTH_BUFFER_BIT; 298 deUint32 point = ndx ? GL_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT; 299 300 if ((m_config.buffers & bit) == 0) 301 continue; /* Not used. */ 302 303 switch (m_config.depthStencilType) 304 { 305 case GL_TEXTURE_2D: context.framebufferTexture2D(GL_FRAMEBUFFER, point, GL_TEXTURE_2D, m_depthStencilBuffer, 0); break; 306 case GL_RENDERBUFFER: context.framebufferRenderbuffer(GL_FRAMEBUFFER, point, GL_RENDERBUFFER, m_depthStencilBuffer); break; 307 default: 308 DE_ASSERT(false); 309 } 310 } 311 312 GLenum err = m_context.getError(); 313 if (err != GL_NO_ERROR) 314 throw glu::Error(err, glu::getErrorStr(err).toString().c_str(), "", __FILE__, __LINE__); 315 316 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 317 } 318 319 Framebuffer::~Framebuffer (void) 320 { 321 m_context.deleteFramebuffers(1, &m_framebuffer); 322 destroyBuffer(m_colorBuffer, m_config.colorType); 323 destroyBuffer(m_depthStencilBuffer, m_config.depthStencilType); 324 } 325 326 void Framebuffer::checkCompleteness (void) 327 { 328 m_context.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer); 329 GLenum status = m_context.checkFramebufferStatus(GL_FRAMEBUFFER); 330 m_context.bindFramebuffer(GL_FRAMEBUFFER, 0); 331 if (status != GL_FRAMEBUFFER_COMPLETE) 332 throw FboIncompleteException(status, __FILE__, __LINE__); 333 } 334 335 deUint32 Framebuffer::createTex2D (deUint32 name, GLenum format, int width, int height) 336 { 337 if (name == 0) 338 m_context.genTextures(1, &name); 339 340 m_context.bindTexture(GL_TEXTURE_2D, name); 341 m_context.texImage2D(GL_TEXTURE_2D, 0, format, width, height); 342 343 if (!deIsPowerOfTwo32(width) || !deIsPowerOfTwo32(height)) 344 { 345 // Set wrap mode to clamp for NPOT FBOs 346 m_context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 347 m_context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 348 } 349 350 m_context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 351 m_context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 352 353 return name; 354 } 355 356 deUint32 Framebuffer::createRbo (deUint32 name, GLenum format, int width, int height) 357 { 358 if (name == 0) 359 m_context.genRenderbuffers(1, &name); 360 361 m_context.bindRenderbuffer(GL_RENDERBUFFER, name); 362 m_context.renderbufferStorage(GL_RENDERBUFFER, format, width, height); 363 364 return name; 365 } 366 367 void Framebuffer::destroyBuffer (deUint32 name, GLenum type) 368 { 369 if (type == GL_TEXTURE_2D || type == GL_TEXTURE_CUBE_MAP) 370 m_context.deleteTextures(1, &name); 371 else if (type == GL_RENDERBUFFER) 372 m_context.deleteRenderbuffers(1, &name); 373 else 374 DE_ASSERT(type == GL_NONE); 375 } 376 377 static void createMetaballsTex2D (sglr::Context& context, deUint32 name, GLenum format, GLenum dataType, int width, int height) 378 { 379 tcu::TextureFormat texFormat = glu::mapGLTransferFormat(format, dataType); 380 tcu::TextureLevel level (texFormat, width, height); 381 382 tcu::fillWithMetaballs(level.getAccess(), 5, name ^ width ^ height); 383 384 context.bindTexture(GL_TEXTURE_2D, name); 385 context.texImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, dataType, level.getAccess().getDataPtr()); 386 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 387 } 388 389 static void createQuadsTex2D (sglr::Context& context, deUint32 name, GLenum format, GLenum dataType, int width, int height) 390 { 391 tcu::TextureFormat texFormat = glu::mapGLTransferFormat(format, dataType); 392 tcu::TextureLevel level (texFormat, width, height); 393 394 tcu::fillWithRGBAQuads(level.getAccess()); 395 396 context.bindTexture(GL_TEXTURE_2D, name); 397 context.texImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, dataType, level.getAccess().getDataPtr()); 398 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 399 } 400 401 class FboRenderCase : public TestCase 402 { 403 public: 404 FboRenderCase (Context& context, const char* name, const char* description, const FboConfig& config); 405 virtual ~FboRenderCase (void) {} 406 407 virtual IterateResult iterate (void); 408 virtual void render (sglr::Context& fboContext, Surface& dst) = DE_NULL; 409 410 bool compare (const tcu::Surface& reference, const tcu::Surface& result); 411 412 protected: 413 const FboConfig m_config; 414 }; 415 416 FboRenderCase::FboRenderCase (Context& context, const char* name, const char* description, const FboConfig& config) 417 : TestCase (context, name, description) 418 , m_config (config) 419 { 420 } 421 422 TestCase::IterateResult FboRenderCase::iterate (void) 423 { 424 tcu::Vec4 clearColor = tcu::Vec4(0.125f, 0.25f, 0.5f, 1.0f); 425 glu::RenderContext& renderCtx = m_context.getRenderContext(); 426 const tcu::RenderTarget& renderTarget = renderCtx.getRenderTarget(); 427 tcu::TestLog& log = m_testCtx.getLog(); 428 const char* failReason = DE_NULL; 429 430 // Position & size for context 431 deRandom rnd; 432 deRandom_init(&rnd, deStringHash(getName())); 433 434 int width = deMin32(renderTarget.getWidth(), 128); 435 int height = deMin32(renderTarget.getHeight(), 128); 436 int xMax = renderTarget.getWidth()-width+1; 437 int yMax = renderTarget.getHeight()-height+1; 438 int x = deRandom_getUint32(&rnd) % xMax; 439 int y = deRandom_getUint32(&rnd) % yMax; 440 441 tcu::Surface gles3Frame (width, height); 442 tcu::Surface refFrame (width, height); 443 GLenum gles3Error; 444 GLenum refError; 445 446 // Render using GLES3 447 try 448 { 449 sglr::GLContext context(renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(x, y, width, height)); 450 451 context.clearColor(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w()); 452 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 453 454 render(context, gles3Frame); // Call actual render func 455 gles3Error = context.getError(); 456 } 457 catch (const FboIncompleteException& e) 458 { 459 if (e.getReason() == GL_FRAMEBUFFER_UNSUPPORTED) 460 { 461 // Mark test case as unsupported 462 log << e; 463 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported"); 464 return STOP; 465 } 466 else 467 throw; // Propagate error 468 } 469 470 // Render reference image 471 { 472 sglr::ReferenceContextBuffers buffers (tcu::PixelFormat(8,8,8,renderTarget.getPixelFormat().alphaBits?8:0), renderTarget.getDepthBits(), renderTarget.getStencilBits(), width, height); 473 sglr::ReferenceContext context (sglr::ReferenceContextLimits(renderCtx), buffers.getColorbuffer(), buffers.getDepthbuffer(), buffers.getStencilbuffer()); 474 475 context.clearColor(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w()); 476 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 477 478 render(context, refFrame); 479 refError = context.getError(); 480 } 481 482 // Compare error codes 483 bool errorCodesOk = (gles3Error == refError); 484 485 if (!errorCodesOk) 486 { 487 log << tcu::TestLog::Message << "Error code mismatch: got " << glu::getErrorStr(gles3Error) << ", expected " << glu::getErrorStr(refError) << tcu::TestLog::EndMessage; 488 failReason = "Got unexpected error"; 489 } 490 491 // Compare images 492 bool imagesOk = compare(refFrame, gles3Frame); 493 494 if (!imagesOk && !failReason) 495 failReason = "Image comparison failed"; 496 497 // Store test result 498 bool isOk = errorCodesOk && imagesOk; 499 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL, 500 isOk ? "Pass" : failReason); 501 502 return STOP; 503 } 504 505 bool FboRenderCase::compare (const tcu::Surface& reference, const tcu::Surface& result) 506 { 507 const tcu::RGBA threshold (tcu::max(getFormatThreshold(m_config.colorFormat), tcu::RGBA(12, 12, 12, 12))); 508 509 return tcu::bilinearCompare(m_testCtx.getLog(), "ComparisonResult", "Image comparison result", reference.getAccess(), result.getAccess(), threshold, tcu::COMPARE_LOG_RESULT); 510 } 511 512 namespace FboCases 513 { 514 515 class StencilClearsTest : public FboRenderCase 516 { 517 public: 518 StencilClearsTest (Context& context, const FboConfig& config); 519 virtual ~StencilClearsTest (void) {}; 520 521 void render (sglr::Context& context, Surface& dst); 522 }; 523 524 StencilClearsTest::StencilClearsTest (Context& context, const FboConfig& config) 525 : FboRenderCase (context, config.getName().c_str(), "Stencil clears", config) 526 { 527 } 528 529 void StencilClearsTest::render (sglr::Context& context, Surface& dst) 530 { 531 tcu::TextureFormat colorFormat = glu::mapGLInternalFormat(m_config.colorFormat); 532 glu::DataType fboSamplerType = glu::getSampler2DType(colorFormat); 533 glu::DataType fboOutputType = getFragmentOutputType(colorFormat); 534 tcu::TextureFormatInfo fboRangeInfo = tcu::getTextureFormatInfo(colorFormat); 535 Vec4 fboOutScale = fboRangeInfo.valueMax - fboRangeInfo.valueMin; 536 Vec4 fboOutBias = fboRangeInfo.valueMin; 537 538 Texture2DShader texToFboShader (DataTypes() << glu::TYPE_SAMPLER_2D, fboOutputType); 539 Texture2DShader texFromFboShader (DataTypes() << fboSamplerType, glu::TYPE_FLOAT_VEC4); 540 541 deUint32 texToFboShaderID = context.createProgram(&texToFboShader); 542 deUint32 texFromFboShaderID = context.createProgram(&texFromFboShader); 543 544 deUint32 metaballsTex = 1; 545 deUint32 quadsTex = 2; 546 int width = 128; 547 int height = 128; 548 549 texToFboShader.setOutScaleBias(fboOutScale, fboOutBias); 550 texFromFboShader.setTexScaleBias(0, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias); 551 552 createQuadsTex2D(context, quadsTex, GL_RGBA, GL_UNSIGNED_BYTE, width, height); 553 createMetaballsTex2D(context, metaballsTex, GL_RGBA, GL_UNSIGNED_BYTE, width, height); 554 555 Framebuffer fbo(context, m_config, width, height); 556 fbo.checkCompleteness(); 557 558 // Bind framebuffer and clear 559 context.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer()); 560 context.viewport(0, 0, width, height); 561 context.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 562 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 563 564 // Do stencil clears 565 context.enable(GL_SCISSOR_TEST); 566 context.scissor(10, 16, 32, 120); 567 context.clearStencil(1); 568 context.clear(GL_STENCIL_BUFFER_BIT); 569 context.scissor(16, 32, 100, 64); 570 context.clearStencil(2); 571 context.clear(GL_STENCIL_BUFFER_BIT); 572 context.disable(GL_SCISSOR_TEST); 573 574 // Draw 2 textures with stecil tests 575 context.enable(GL_STENCIL_TEST); 576 577 context.bindTexture(GL_TEXTURE_2D, quadsTex); 578 context.stencilFunc(GL_EQUAL, 1, 0xffu); 579 580 texToFboShader.setUniforms(context, texToFboShaderID); 581 sglr::drawQuad(context, texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f)); 582 583 context.bindTexture(GL_TEXTURE_2D, metaballsTex); 584 context.stencilFunc(GL_EQUAL, 2, 0xffu); 585 586 texToFboShader.setUniforms(context, texToFboShaderID); 587 sglr::drawQuad(context, texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f)); 588 589 context.disable(GL_STENCIL_TEST); 590 591 if (fbo.getConfig().colorType == GL_TEXTURE_2D) 592 { 593 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 594 context.bindTexture(GL_TEXTURE_2D, fbo.getColorBuffer()); 595 context.viewport(0, 0, context.getWidth(), context.getHeight()); 596 597 texFromFboShader.setUniforms(context, texFromFboShaderID); 598 sglr::drawQuad(context, texFromFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 599 600 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight()); 601 } 602 else 603 readPixels(context, dst, 0, 0, width, height, colorFormat, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias); 604 } 605 606 class SharedColorbufferTest : public FboRenderCase 607 { 608 public: 609 SharedColorbufferTest (Context& context, const FboConfig& config); 610 virtual ~SharedColorbufferTest (void) {}; 611 612 void render (sglr::Context& context, Surface& dst); 613 }; 614 615 SharedColorbufferTest::SharedColorbufferTest (Context& context, const FboConfig& config) 616 : FboRenderCase (context, config.getName().c_str(), "Shared colorbuffer", config) 617 { 618 } 619 620 void SharedColorbufferTest::render (sglr::Context& context, Surface& dst) 621 { 622 Texture2DShader texShader (DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4); 623 FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); 624 deUint32 texShaderID = context.createProgram(&texShader); 625 deUint32 flatShaderID = context.createProgram(&flatShader); 626 627 int width = 128; 628 int height = 128; 629 deUint32 quadsTex = 1; 630 deUint32 metaballsTex = 2; 631 bool stencil = (m_config.buffers & GL_STENCIL_BUFFER_BIT) != 0; 632 633 context.disable(GL_DITHER); 634 635 // Textures 636 createQuadsTex2D(context, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64); 637 createMetaballsTex2D(context, metaballsTex, GL_RGBA, GL_UNSIGNED_BYTE, 64, 64); 638 639 context.viewport(0, 0, width, height); 640 641 // Fbo A 642 Framebuffer fboA(context, m_config, width, height); 643 fboA.checkCompleteness(); 644 645 // Fbo B - don't create colorbuffer 646 FboConfig cfg = m_config; 647 cfg.buffers &= ~GL_COLOR_BUFFER_BIT; 648 cfg.colorType = GL_NONE; 649 cfg.colorFormat = GL_NONE; 650 Framebuffer fboB(context, cfg, width, height); 651 652 // Attach color buffer from fbo A 653 context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer()); 654 switch (m_config.colorType) 655 { 656 case GL_TEXTURE_2D: 657 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboA.getColorBuffer(), 0); 658 break; 659 660 case GL_RENDERBUFFER: 661 context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fboA.getColorBuffer()); 662 break; 663 664 default: 665 DE_ASSERT(DE_FALSE); 666 } 667 668 // Clear depth and stencil in fbo B 669 context.clear(GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 670 671 // Render quads to fbo 1, with depth 0.0 672 context.bindFramebuffer(GL_FRAMEBUFFER, fboA.getFramebuffer()); 673 context.bindTexture(GL_TEXTURE_2D, quadsTex); 674 context.clearColor(0.0f, 0.0f, 0.0f, 1.0f); 675 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 676 677 if (stencil) 678 { 679 // Stencil to 1 in fbo A 680 context.clearStencil(1); 681 context.clear(GL_STENCIL_BUFFER_BIT); 682 } 683 684 texShader.setUniforms(context, texShaderID); 685 686 context.enable(GL_DEPTH_TEST); 687 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 688 context.disable(GL_DEPTH_TEST); 689 690 // Blend metaballs to fbo 2 691 context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer()); 692 context.bindTexture(GL_TEXTURE_2D, metaballsTex); 693 context.enable(GL_BLEND); 694 context.blendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE); 695 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 696 697 // Render small quad that is only visible if depth buffer is not shared with fbo A - or there is no depth bits 698 context.bindTexture(GL_TEXTURE_2D, quadsTex); 699 context.enable(GL_DEPTH_TEST); 700 sglr::drawQuad(context, texShaderID, Vec3(0.5f, 0.5f, 0.5f), Vec3(1.0f, 1.0f, 0.5f)); 701 context.disable(GL_DEPTH_TEST); 702 703 if (stencil) 704 { 705 flatShader.setColor(context, flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 706 707 // Clear subset of stencil buffer to 1 708 context.enable(GL_SCISSOR_TEST); 709 context.scissor(10, 10, 12, 25); 710 context.clearStencil(1); 711 context.clear(GL_STENCIL_BUFFER_BIT); 712 context.disable(GL_SCISSOR_TEST); 713 714 // Render quad with stencil mask == 1 715 context.enable(GL_STENCIL_TEST); 716 context.stencilFunc(GL_EQUAL, 1, 0xffu); 717 sglr::drawQuad(context, flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 718 context.disable(GL_STENCIL_TEST); 719 } 720 721 // Get results 722 if (fboA.getConfig().colorType == GL_TEXTURE_2D) 723 { 724 texShader.setUniforms(context, texShaderID); 725 726 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 727 context.bindTexture(GL_TEXTURE_2D, fboA.getColorBuffer()); 728 context.viewport(0, 0, context.getWidth(), context.getHeight()); 729 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 730 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight()); 731 } 732 else 733 readPixels(context, dst, 0, 0, width, height, glu::mapGLInternalFormat(fboA.getConfig().colorFormat), Vec4(1.0f), Vec4(0.0f)); 734 } 735 736 class SharedColorbufferClearsTest : public FboRenderCase 737 { 738 public: 739 SharedColorbufferClearsTest (Context& context, const FboConfig& config); 740 virtual ~SharedColorbufferClearsTest (void) {} 741 742 void render (sglr::Context& context, Surface& dst); 743 }; 744 745 SharedColorbufferClearsTest::SharedColorbufferClearsTest (Context& context, const FboConfig& config) 746 : FboRenderCase (context, config.getName().c_str(), "Shared colorbuffer clears", config) 747 { 748 } 749 750 void SharedColorbufferClearsTest::render (sglr::Context& context, Surface& dst) 751 { 752 tcu::TextureFormat colorFormat = glu::mapGLInternalFormat(m_config.colorFormat); 753 glu::DataType fboSamplerType = glu::getSampler2DType(colorFormat); 754 int width = 128; 755 int height = 128; 756 deUint32 colorbuffer = 1; 757 758 // Check for format support. 759 checkColorFormatSupport(context, m_config.colorFormat); 760 761 // Single colorbuffer 762 if (m_config.colorType == GL_TEXTURE_2D) 763 { 764 context.bindTexture(GL_TEXTURE_2D, colorbuffer); 765 context.texImage2D(GL_TEXTURE_2D, 0, m_config.colorFormat, width, height); 766 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 767 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 768 } 769 else 770 { 771 DE_ASSERT(m_config.colorType == GL_RENDERBUFFER); 772 context.bindRenderbuffer(GL_RENDERBUFFER, colorbuffer); 773 context.renderbufferStorage(GL_RENDERBUFFER, m_config.colorFormat, width, height); 774 } 775 776 // Multiple framebuffers sharing the colorbuffer 777 for (int fbo = 1; fbo <= 3; fbo++) 778 { 779 context.bindFramebuffer(GL_FRAMEBUFFER, fbo); 780 781 if (m_config.colorType == GL_TEXTURE_2D) 782 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0); 783 else 784 context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuffer); 785 } 786 787 context.bindFramebuffer(GL_FRAMEBUFFER, 1); 788 789 // Check completeness 790 { 791 GLenum status = context.checkFramebufferStatus(GL_FRAMEBUFFER); 792 if (status != GL_FRAMEBUFFER_COMPLETE) 793 throw FboIncompleteException(status, __FILE__, __LINE__); 794 } 795 796 // Render to them 797 context.viewport(0, 0, width, height); 798 context.clearColor(0.0f, 0.0f, 1.0f, 1.0f); 799 context.clear(GL_COLOR_BUFFER_BIT); 800 801 context.enable(GL_SCISSOR_TEST); 802 803 context.bindFramebuffer(GL_FRAMEBUFFER, 2); 804 context.clearColor(0.6f, 0.0f, 0.0f, 1.0f); 805 context.scissor(10, 10, 64, 64); 806 context.clear(GL_COLOR_BUFFER_BIT); 807 context.clearColor(0.0f, 0.6f, 0.0f, 1.0f); 808 context.scissor(60, 60, 40, 20); 809 context.clear(GL_COLOR_BUFFER_BIT); 810 811 context.bindFramebuffer(GL_FRAMEBUFFER, 3); 812 context.clearColor(0.0f, 0.0f, 0.6f, 1.0f); 813 context.scissor(20, 20, 100, 10); 814 context.clear(GL_COLOR_BUFFER_BIT); 815 816 context.bindFramebuffer(GL_FRAMEBUFFER, 1); 817 context.clearColor(0.6f, 0.0f, 0.6f, 1.0f); 818 context.scissor(20, 20, 5, 100); 819 context.clear(GL_COLOR_BUFFER_BIT); 820 821 context.disable(GL_SCISSOR_TEST); 822 823 if (m_config.colorType == GL_TEXTURE_2D) 824 { 825 Texture2DShader shader(DataTypes() << fboSamplerType, glu::TYPE_FLOAT_VEC4); 826 deUint32 shaderID = context.createProgram(&shader); 827 828 shader.setUniforms(context, shaderID); 829 830 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 831 context.viewport(0, 0, context.getWidth(), context.getHeight()); 832 sglr::drawQuad(context, shaderID, Vec3(-0.9f, -0.9f, 0.0f), Vec3(0.9f, 0.9f, 0.0f)); 833 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight()); 834 } 835 else 836 readPixels(context, dst, 0, 0, width, height, colorFormat, Vec4(1.0f), Vec4(0.0f)); 837 } 838 839 class SharedDepthStencilTest : public FboRenderCase 840 { 841 public: 842 SharedDepthStencilTest (Context& context, const FboConfig& config); 843 virtual ~SharedDepthStencilTest (void) {}; 844 845 static bool isConfigSupported (const FboConfig& config); 846 void render (sglr::Context& context, Surface& dst); 847 }; 848 849 SharedDepthStencilTest::SharedDepthStencilTest (Context& context, const FboConfig& config) 850 : FboRenderCase (context, config.getName().c_str(), "Shared depth/stencilbuffer", config) 851 { 852 } 853 854 bool SharedDepthStencilTest::isConfigSupported (const FboConfig& config) 855 { 856 return (config.buffers & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) != 0; 857 } 858 859 void SharedDepthStencilTest::render (sglr::Context& context, Surface& dst) 860 { 861 Texture2DShader texShader (DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4); 862 FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); 863 deUint32 texShaderID = context.createProgram(&texShader); 864 deUint32 flatShaderID = context.createProgram(&flatShader); 865 int width = 128; 866 int height = 128; 867 // bool depth = (m_config.buffers & GL_DEPTH_BUFFER_BIT) != 0; 868 bool stencil = (m_config.buffers & GL_STENCIL_BUFFER_BIT) != 0; 869 870 // Textures 871 deUint32 metaballsTex = 5; 872 deUint32 quadsTex = 6; 873 createMetaballsTex2D(context, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64); 874 createQuadsTex2D(context, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64); 875 876 context.viewport(0, 0, width, height); 877 878 // Fbo A 879 Framebuffer fboA(context, m_config, width, height); 880 fboA.checkCompleteness(); 881 882 // Fbo B 883 FboConfig cfg = m_config; 884 cfg.buffers &= ~(GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 885 cfg.depthStencilType = GL_NONE; 886 cfg.depthStencilFormat = GL_NONE; 887 Framebuffer fboB(context, cfg, width, height); 888 889 // Bind depth/stencil buffers from fbo A to fbo B 890 context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer()); 891 for (int ndx = 0; ndx < 2; ndx++) 892 { 893 deUint32 bit = ndx ? GL_STENCIL_BUFFER_BIT : GL_DEPTH_BUFFER_BIT; 894 deUint32 point = ndx ? GL_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT; 895 896 if ((m_config.buffers & bit) == 0) 897 continue; 898 899 switch (m_config.depthStencilType) 900 { 901 case GL_TEXTURE_2D: context.framebufferTexture2D(GL_FRAMEBUFFER, point, GL_TEXTURE_2D, fboA.getDepthStencilBuffer(), 0); break; 902 case GL_RENDERBUFFER: context.framebufferRenderbuffer(GL_FRAMEBUFFER, point, GL_RENDERBUFFER, fboA.getDepthStencilBuffer()); break; 903 default: 904 TCU_FAIL("Not implemented"); 905 } 906 } 907 908 // Setup uniforms 909 texShader.setUniforms(context, texShaderID); 910 911 // Clear color to red and stencil to 1 in fbo B. 912 context.clearColor(1.0f, 0.0f, 0.0f, 1.0f); 913 context.clearStencil(1); 914 context.clear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 915 916 context.enable(GL_DEPTH_TEST); 917 918 // Render quad to fbo A 919 context.bindFramebuffer(GL_FRAMEBUFFER, fboA.getFramebuffer()); 920 context.bindTexture(GL_TEXTURE_2D, quadsTex); 921 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 922 923 if (stencil) 924 { 925 // Clear subset of stencil buffer to 0 in fbo A 926 context.enable(GL_SCISSOR_TEST); 927 context.scissor(10, 10, 12, 25); 928 context.clearStencil(0); 929 context.clear(GL_STENCIL_BUFFER_BIT); 930 context.disable(GL_SCISSOR_TEST); 931 } 932 933 // Render metaballs to fbo B 934 context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer()); 935 context.bindTexture(GL_TEXTURE_2D, metaballsTex); 936 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); 937 938 context.disable(GL_DEPTH_TEST); 939 940 if (stencil) 941 { 942 // Render quad with stencil mask == 0 943 context.enable(GL_STENCIL_TEST); 944 context.stencilFunc(GL_EQUAL, 0, 0xffu); 945 context.useProgram(flatShaderID); 946 flatShader.setColor(context, flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)); 947 sglr::drawQuad(context, flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f)); 948 context.disable(GL_STENCIL_TEST); 949 } 950 951 if (m_config.colorType == GL_TEXTURE_2D) 952 { 953 // Render both to screen 954 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 955 context.viewport(0, 0, context.getWidth(), context.getHeight()); 956 context.bindTexture(GL_TEXTURE_2D, fboA.getColorBuffer()); 957 sglr::drawQuad(context, texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(0.0f, 1.0f, 0.0f)); 958 context.bindTexture(GL_TEXTURE_2D, fboB.getColorBuffer()); 959 sglr::drawQuad(context, texShaderID, Vec3(0.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 960 961 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight()); 962 } 963 else 964 { 965 // Read results from fbo B 966 readPixels(context, dst, 0, 0, width, height, glu::mapGLInternalFormat(m_config.colorFormat), Vec4(1.0f), Vec4(0.0f)); 967 } 968 } 969 970 #if 0 971 class TexSubImageAfterRenderTest : public FboRenderCase 972 { 973 public: 974 TexSubImageAfterRenderTest (Context& context, const FboConfig& config); 975 virtual ~TexSubImageAfterRenderTest (void) {} 976 977 void render (sglr::Context& context, Surface& dst); 978 }; 979 980 TexSubImageAfterRenderTest::TexSubImageAfterRenderTest (Context& context, const FboConfig& config) 981 : FboRenderCase(context, (string("after_render_") + config.getName()).c_str(), "TexSubImage after rendering to texture", config) 982 { 983 } 984 985 void TexSubImageAfterRenderTest::render (sglr::Context& context, Surface& dst) 986 { 987 using sglr::TexturedQuadOp; 988 989 bool isRGBA = true; 990 991 Surface fourQuads(Surface::PIXELFORMAT_RGB, 64, 64); 992 tcu::SurfaceUtil::fillWithFourQuads(fourQuads); 993 994 Surface metaballs(isRGBA ? Surface::PIXELFORMAT_RGBA : Surface::PIXELFORMAT_RGB, 64, 64); 995 tcu::SurfaceUtil::fillWithMetaballs(metaballs, 5, 3); 996 997 deUint32 fourQuadsTex = 1; 998 context.bindTexture(GL_TEXTURE_2D, fourQuadsTex); 999 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1000 context.texImage2D(GL_TEXTURE_2D, 0, GL_RGB, fourQuads); 1001 1002 context.bindFramebuffer(GL_FRAMEBUFFER, 1); 1003 1004 deUint32 fboTex = 2; 1005 context.bindTexture(GL_TEXTURE_2D, fboTex); 1006 context.texImage2D(GL_TEXTURE_2D, 0, isRGBA ? GL_RGBA : GL_RGB, 128, 128); 1007 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1008 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex, 0); 1009 1010 // Render to fbo 1011 context.viewport(0, 0, 128, 128); 1012 context.bindTexture(GL_TEXTURE_2D, fourQuadsTex); 1013 context.draw(TexturedQuadOp(-1.0f, -1.0f, 1.0f, 1.0f, 0)); 1014 1015 // Update texture using TexSubImage2D 1016 context.bindTexture(GL_TEXTURE_2D, fboTex); 1017 context.texSubImage2D(GL_TEXTURE_2D, 0, 32, 32, metaballs); 1018 1019 // Draw to screen 1020 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 1021 context.viewport(0, 0, context.getWidth(), context.getHeight()); 1022 context.draw(TexturedQuadOp(-1.0f, -1.0f, 1.0f, 1.0f, 0)); 1023 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight()); 1024 } 1025 1026 class TexSubImageBetweenRenderTest : public FboRenderCase 1027 { 1028 public: 1029 TexSubImageBetweenRenderTest (Context& context, const FboConfig& config); 1030 virtual ~TexSubImageBetweenRenderTest (void) {} 1031 1032 void render (sglr::Context& context, Surface& dst); 1033 }; 1034 1035 TexSubImageBetweenRenderTest::TexSubImageBetweenRenderTest (Context& context, const FboConfig& config) 1036 : FboRenderCase(context, (string("between_render_") + config.getName()).c_str(), "TexSubImage between rendering calls", config) 1037 { 1038 } 1039 1040 void TexSubImageBetweenRenderTest::render (sglr::Context& context, Surface& dst) 1041 { 1042 using sglr::TexturedQuadOp; 1043 using sglr::BlendTextureOp; 1044 1045 bool isRGBA = true; 1046 1047 Surface fourQuads(Surface::PIXELFORMAT_RGB, 64, 64); 1048 tcu::SurfaceUtil::fillWithFourQuads(fourQuads); 1049 1050 Surface metaballs(isRGBA ? Surface::PIXELFORMAT_RGBA : Surface::PIXELFORMAT_RGB, 64, 64); 1051 tcu::SurfaceUtil::fillWithMetaballs(metaballs, 5, 3); 1052 1053 Surface metaballs2(Surface::PIXELFORMAT_RGBA, 64, 64); 1054 tcu::SurfaceUtil::fillWithMetaballs(metaballs2, 5, 4); 1055 1056 deUint32 metaballsTex = 3; 1057 context.bindTexture(GL_TEXTURE_2D, metaballsTex); 1058 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1059 context.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, metaballs2); 1060 1061 deUint32 fourQuadsTex = 1; 1062 context.bindTexture(GL_TEXTURE_2D, fourQuadsTex); 1063 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1064 context.texImage2D(GL_TEXTURE_2D, 0, GL_RGB, fourQuads); 1065 1066 context.bindFramebuffer(GL_FRAMEBUFFER, 1); 1067 1068 deUint32 fboTex = 2; 1069 context.bindTexture(GL_TEXTURE_2D, fboTex); 1070 context.texImage2D(GL_TEXTURE_2D, 0, isRGBA ? GL_RGBA : GL_RGB, 128, 128); 1071 context.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1072 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex, 0); 1073 1074 // Render to fbo 1075 context.viewport(0, 0, 128, 128); 1076 context.bindTexture(GL_TEXTURE_2D, fourQuadsTex); 1077 context.draw(TexturedQuadOp(-1.0f, -1.0f, 1.0f, 1.0f, 0)); 1078 1079 // Update texture using TexSubImage2D 1080 context.bindTexture(GL_TEXTURE_2D, fboTex); 1081 context.texSubImage2D(GL_TEXTURE_2D, 0, 32, 32, metaballs); 1082 1083 // Render again to fbo 1084 context.bindTexture(GL_TEXTURE_2D, metaballsTex); 1085 context.draw(BlendTextureOp(0)); 1086 1087 // Draw to screen 1088 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 1089 context.viewport(0, 0, context.getWidth(), context.getHeight()); 1090 context.bindTexture(GL_TEXTURE_2D, fboTex); 1091 context.draw(TexturedQuadOp(-1.0f, -1.0f, 1.0f, 1.0f, 0)); 1092 1093 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight()); 1094 } 1095 #endif 1096 1097 class ResizeTest : public FboRenderCase 1098 { 1099 public: 1100 ResizeTest (Context& context, const FboConfig& config); 1101 virtual ~ResizeTest (void) {} 1102 1103 void render (sglr::Context& context, Surface& dst); 1104 }; 1105 1106 ResizeTest::ResizeTest (Context& context, const FboConfig& config) 1107 : FboRenderCase (context, config.getName().c_str(), "Resize framebuffer", config) 1108 { 1109 } 1110 1111 void ResizeTest::render (sglr::Context& context, Surface& dst) 1112 { 1113 tcu::TextureFormat colorFormat = glu::mapGLInternalFormat(m_config.colorFormat); 1114 glu::DataType fboSamplerType = glu::getSampler2DType(colorFormat); 1115 glu::DataType fboOutputType = getFragmentOutputType(colorFormat); 1116 tcu::TextureFormatInfo fboRangeInfo = tcu::getTextureFormatInfo(colorFormat); 1117 Vec4 fboOutScale = fboRangeInfo.valueMax - fboRangeInfo.valueMin; 1118 Vec4 fboOutBias = fboRangeInfo.valueMin; 1119 1120 Texture2DShader texToFboShader (DataTypes() << glu::TYPE_SAMPLER_2D, fboOutputType); 1121 Texture2DShader texFromFboShader (DataTypes() << fboSamplerType, glu::TYPE_FLOAT_VEC4); 1122 FlatColorShader flatShader (fboOutputType); 1123 deUint32 texToFboShaderID = context.createProgram(&texToFboShader); 1124 deUint32 texFromFboShaderID = context.createProgram(&texFromFboShader); 1125 deUint32 flatShaderID = context.createProgram(&flatShader); 1126 1127 deUint32 quadsTex = 1; 1128 deUint32 metaballsTex = 2; 1129 bool depth = (m_config.buffers & GL_DEPTH_BUFFER_BIT) != 0; 1130 bool stencil = (m_config.buffers & GL_STENCIL_BUFFER_BIT) != 0; 1131 int initialWidth = 128; 1132 int initialHeight = 128; 1133 int newWidth = 64; 1134 int newHeight = 32; 1135 1136 texToFboShader.setOutScaleBias(fboOutScale, fboOutBias); 1137 texFromFboShader.setTexScaleBias(0, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias); 1138 1139 createQuadsTex2D(context, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64); 1140 createMetaballsTex2D(context, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 32, 32); 1141 1142 Framebuffer fbo(context, m_config, initialWidth, initialHeight); 1143 fbo.checkCompleteness(); 1144 1145 // Setup shaders 1146 texToFboShader.setUniforms (context, texToFboShaderID); 1147 texFromFboShader.setUniforms(context, texFromFboShaderID); 1148 flatShader.setColor (context, flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f) * fboOutScale + fboOutBias); 1149 1150 // Render quads 1151 context.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer()); 1152 context.viewport(0, 0, initialWidth, initialHeight); 1153 clearColorBuffer(context, colorFormat, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); 1154 context.clear(GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 1155 context.bindTexture(GL_TEXTURE_2D, quadsTex); 1156 sglr::drawQuad(context, texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1157 1158 if (fbo.getConfig().colorType == GL_TEXTURE_2D) 1159 { 1160 // Render fbo to screen 1161 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 1162 context.viewport(0, 0, context.getWidth(), context.getHeight()); 1163 context.bindTexture(GL_TEXTURE_2D, fbo.getColorBuffer()); 1164 sglr::drawQuad(context, texFromFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1165 1166 // Restore binding 1167 context.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer()); 1168 } 1169 1170 // Resize buffers 1171 switch (fbo.getConfig().colorType) 1172 { 1173 case GL_TEXTURE_2D: 1174 context.bindTexture(GL_TEXTURE_2D, fbo.getColorBuffer()); 1175 context.texImage2D(GL_TEXTURE_2D, 0, fbo.getConfig().colorFormat, newWidth, newHeight); 1176 break; 1177 1178 case GL_RENDERBUFFER: 1179 context.bindRenderbuffer(GL_RENDERBUFFER, fbo.getColorBuffer()); 1180 context.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().colorFormat, newWidth, newHeight); 1181 break; 1182 1183 default: 1184 DE_ASSERT(DE_FALSE); 1185 } 1186 1187 if (depth || stencil) 1188 { 1189 switch (fbo.getConfig().depthStencilType) 1190 { 1191 case GL_TEXTURE_2D: 1192 context.bindTexture(GL_TEXTURE_2D, fbo.getDepthStencilBuffer()); 1193 context.texImage2D(GL_TEXTURE_2D, 0, fbo.getConfig().depthStencilFormat, newWidth, newHeight); 1194 break; 1195 1196 case GL_RENDERBUFFER: 1197 context.bindRenderbuffer(GL_RENDERBUFFER, fbo.getDepthStencilBuffer()); 1198 context.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().depthStencilFormat, newWidth, newHeight); 1199 break; 1200 1201 default: 1202 DE_ASSERT(false); 1203 } 1204 } 1205 1206 // Render to resized fbo 1207 context.viewport(0, 0, newWidth, newHeight); 1208 clearColorBuffer(context, colorFormat, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 1209 context.clear(GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 1210 1211 context.enable(GL_DEPTH_TEST); 1212 1213 context.bindTexture(GL_TEXTURE_2D, metaballsTex); 1214 sglr::drawQuad(context, texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f)); 1215 1216 context.bindTexture(GL_TEXTURE_2D, quadsTex); 1217 sglr::drawQuad(context, texToFboShaderID, Vec3(0.0f, 0.0f, -1.0f), Vec3(+1.0f, +1.0f, 1.0f)); 1218 1219 context.disable(GL_DEPTH_TEST); 1220 1221 if (stencil) 1222 { 1223 context.enable(GL_SCISSOR_TEST); 1224 context.clearStencil(1); 1225 context.scissor(10, 10, 5, 15); 1226 context.clear(GL_STENCIL_BUFFER_BIT); 1227 context.disable(GL_SCISSOR_TEST); 1228 1229 context.enable(GL_STENCIL_TEST); 1230 context.stencilFunc(GL_EQUAL, 1, 0xffu); 1231 sglr::drawQuad(context, flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f)); 1232 context.disable(GL_STENCIL_TEST); 1233 } 1234 1235 if (m_config.colorType == GL_TEXTURE_2D) 1236 { 1237 context.bindFramebuffer(GL_FRAMEBUFFER, 0); 1238 context.viewport(0, 0, context.getWidth(), context.getHeight()); 1239 context.bindTexture(GL_TEXTURE_2D, fbo.getColorBuffer()); 1240 sglr::drawQuad(context, texFromFboShaderID, Vec3(-0.5f, -0.5f, 0.0f), Vec3(0.5f, 0.5f, 0.0f)); 1241 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight()); 1242 } 1243 else 1244 readPixels(context, dst, 0, 0, newWidth, newHeight, colorFormat, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias); 1245 } 1246 1247 class RecreateBuffersTest : public FboRenderCase 1248 { 1249 public: 1250 RecreateBuffersTest (Context& context, const FboConfig& config, deUint32 buffers, bool rebind); 1251 virtual ~RecreateBuffersTest (void) {} 1252 1253 void render (sglr::Context& context, Surface& dst); 1254 1255 private: 1256 deUint32 m_buffers; 1257 bool m_rebind; 1258 }; 1259 1260 RecreateBuffersTest::RecreateBuffersTest (Context& context, const FboConfig& config, deUint32 buffers, bool rebind) 1261 : FboRenderCase (context, (string(config.getName()) + (rebind ? "" : "_no_rebind")).c_str(), "Recreate buffers", config) 1262 , m_buffers (buffers) 1263 , m_rebind (rebind) 1264 { 1265 } 1266 1267 void RecreateBuffersTest::render (sglr::Context& ctx, Surface& dst) 1268 { 1269 tcu::TextureFormat colorFormat = glu::mapGLInternalFormat(m_config.colorFormat); 1270 glu::DataType fboSamplerType = glu::getSampler2DType(colorFormat); 1271 glu::DataType fboOutputType = getFragmentOutputType(colorFormat); 1272 tcu::TextureFormatInfo fboRangeInfo = tcu::getTextureFormatInfo(colorFormat); 1273 Vec4 fboOutScale = fboRangeInfo.valueMax - fboRangeInfo.valueMin; 1274 Vec4 fboOutBias = fboRangeInfo.valueMin; 1275 1276 Texture2DShader texToFboShader (DataTypes() << glu::TYPE_SAMPLER_2D, fboOutputType); 1277 Texture2DShader texFromFboShader (DataTypes() << fboSamplerType, glu::TYPE_FLOAT_VEC4); 1278 FlatColorShader flatShader (fboOutputType); 1279 deUint32 texToFboShaderID = ctx.createProgram(&texToFboShader); 1280 deUint32 texFromFboShaderID = ctx.createProgram(&texFromFboShader); 1281 deUint32 flatShaderID = ctx.createProgram(&flatShader); 1282 1283 int width = 128; 1284 int height = 128; 1285 deUint32 metaballsTex = 1; 1286 deUint32 quadsTex = 2; 1287 bool stencil = (m_config.buffers & GL_STENCIL_BUFFER_BIT) != 0; 1288 1289 createQuadsTex2D(ctx, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64); 1290 createMetaballsTex2D(ctx, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64); 1291 1292 Framebuffer fbo(ctx, m_config, width, height); 1293 fbo.checkCompleteness(); 1294 1295 // Setup shaders 1296 texToFboShader.setOutScaleBias(fboOutScale, fboOutBias); 1297 texFromFboShader.setTexScaleBias(0, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias); 1298 texToFboShader.setUniforms (ctx, texToFboShaderID); 1299 texFromFboShader.setUniforms(ctx, texFromFboShaderID); 1300 flatShader.setColor (ctx, flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f) * fboOutScale + fboOutBias); 1301 1302 // Draw scene 1303 ctx.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer()); 1304 ctx.viewport(0, 0, width, height); 1305 clearColorBuffer(ctx, colorFormat, tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); 1306 ctx.clear(GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 1307 1308 ctx.enable(GL_DEPTH_TEST); 1309 1310 ctx.bindTexture(GL_TEXTURE_2D, quadsTex); 1311 sglr::drawQuad(ctx, texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1312 1313 ctx.disable(GL_DEPTH_TEST); 1314 1315 if (stencil) 1316 { 1317 ctx.enable(GL_SCISSOR_TEST); 1318 ctx.scissor(width/4, height/4, width/2, height/2); 1319 ctx.clearStencil(1); 1320 ctx.clear(GL_STENCIL_BUFFER_BIT); 1321 ctx.disable(GL_SCISSOR_TEST); 1322 } 1323 1324 // Recreate buffers 1325 if (!m_rebind) 1326 ctx.bindFramebuffer(GL_FRAMEBUFFER, 0); 1327 1328 DE_ASSERT((m_buffers & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) == 0 || 1329 (m_buffers & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) == (m_config.buffers & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT))); 1330 1331 // Recreate. 1332 for (int ndx = 0; ndx < 2; ndx++) 1333 { 1334 deUint32 bit = ndx == 0 ? GL_COLOR_BUFFER_BIT 1335 : (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); 1336 deUint32 type = ndx == 0 ? fbo.getConfig().colorType 1337 : fbo.getConfig().depthStencilType; 1338 deUint32 format = ndx == 0 ? fbo.getConfig().colorFormat 1339 : fbo.getConfig().depthStencilFormat; 1340 deUint32 buf = ndx == 0 ? fbo.getColorBuffer() 1341 : fbo.getDepthStencilBuffer(); 1342 1343 if ((m_buffers & bit) == 0) 1344 continue; 1345 1346 switch (type) 1347 { 1348 case GL_TEXTURE_2D: 1349 ctx.deleteTextures(1, &buf); 1350 ctx.bindTexture(GL_TEXTURE_2D, buf); 1351 ctx.texImage2D(GL_TEXTURE_2D, 0, format, width, height); 1352 ctx.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 1353 ctx.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 1354 break; 1355 1356 case GL_RENDERBUFFER: 1357 ctx.deleteRenderbuffers(1, &buf); 1358 ctx.bindRenderbuffer(GL_RENDERBUFFER, buf); 1359 ctx.renderbufferStorage(GL_RENDERBUFFER, format, width, height); 1360 break; 1361 1362 default: 1363 DE_ASSERT(false); 1364 } 1365 } 1366 1367 // Rebind. 1368 if (m_rebind) 1369 { 1370 for (int ndx = 0; ndx < 3; ndx++) 1371 { 1372 deUint32 bit = ndx == 0 ? GL_COLOR_BUFFER_BIT : 1373 ndx == 1 ? GL_DEPTH_BUFFER_BIT : 1374 ndx == 2 ? GL_STENCIL_BUFFER_BIT : 0; 1375 deUint32 point = ndx == 0 ? GL_COLOR_ATTACHMENT0 : 1376 ndx == 1 ? GL_DEPTH_ATTACHMENT : 1377 ndx == 2 ? GL_STENCIL_ATTACHMENT : 0; 1378 deUint32 type = ndx == 0 ? fbo.getConfig().colorType 1379 : fbo.getConfig().depthStencilType; 1380 deUint32 buf = ndx == 0 ? fbo.getColorBuffer() 1381 : fbo.getDepthStencilBuffer(); 1382 1383 if ((m_buffers & bit) == 0) 1384 continue; 1385 1386 switch (type) 1387 { 1388 case GL_TEXTURE_2D: 1389 ctx.framebufferTexture2D(GL_FRAMEBUFFER, point, GL_TEXTURE_2D, buf, 0); 1390 break; 1391 1392 case GL_RENDERBUFFER: 1393 ctx.framebufferRenderbuffer(GL_FRAMEBUFFER, point, GL_RENDERBUFFER, buf); 1394 break; 1395 1396 default: 1397 DE_ASSERT(false); 1398 } 1399 } 1400 } 1401 1402 if (!m_rebind) 1403 ctx.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer()); 1404 1405 ctx.clearStencil(0); 1406 ctx.clear(m_buffers & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); // \note Clear only buffers that were re-created 1407 if (m_buffers & GL_COLOR_BUFFER_BIT) 1408 { 1409 // Clearing of integer buffers is undefined so do clearing by rendering flat color. 1410 sglr::drawQuad(ctx, flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1411 } 1412 1413 ctx.enable(GL_DEPTH_TEST); 1414 1415 if (stencil) 1416 { 1417 // \note Stencil test enabled only if we have stencil buffer 1418 ctx.enable(GL_STENCIL_TEST); 1419 ctx.stencilFunc(GL_EQUAL, 0, 0xffu); 1420 } 1421 ctx.bindTexture(GL_TEXTURE_2D, metaballsTex); 1422 sglr::drawQuad(ctx, texToFboShaderID, Vec3(-1.0f, -1.0f, 1.0f), Vec3(1.0f, 1.0f, -1.0f)); 1423 if (stencil) 1424 ctx.disable(GL_STENCIL_TEST); 1425 1426 ctx.disable(GL_DEPTH_TEST); 1427 1428 if (fbo.getConfig().colorType == GL_TEXTURE_2D) 1429 { 1430 // Unbind fbo 1431 ctx.bindFramebuffer(GL_FRAMEBUFFER, 0); 1432 1433 // Draw to screen 1434 ctx.bindTexture(GL_TEXTURE_2D, fbo.getColorBuffer()); 1435 ctx.viewport(0, 0, ctx.getWidth(), ctx.getHeight()); 1436 sglr::drawQuad(ctx, texFromFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); 1437 1438 // Read from screen 1439 ctx.readPixels(dst, 0, 0, ctx.getWidth(), ctx.getHeight()); 1440 } 1441 else 1442 { 1443 // Read from fbo 1444 readPixels(ctx, dst, 0, 0, width, height, colorFormat, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias); 1445 } 1446 } 1447 1448 } // FboCases 1449 1450 FboRenderTestGroup::FboRenderTestGroup (Context& context) 1451 : TestCaseGroup(context, "render", "Rendering Tests") 1452 { 1453 } 1454 1455 FboRenderTestGroup::~FboRenderTestGroup (void) 1456 { 1457 } 1458 1459 void FboRenderTestGroup::init (void) 1460 { 1461 static const deUint32 objectTypes[] = 1462 { 1463 GL_TEXTURE_2D, 1464 GL_RENDERBUFFER 1465 }; 1466 1467 enum FormatType 1468 { 1469 FORMATTYPE_FLOAT = 0, 1470 FORMATTYPE_FIXED, 1471 FORMATTYPE_INT, 1472 FORMATTYPE_UINT, 1473 1474 FORMATTYPE_LAST 1475 }; 1476 1477 // Required by specification. 1478 static const struct 1479 { 1480 deUint32 format; 1481 FormatType type; 1482 } colorFormats[] = 1483 { 1484 { GL_RGBA32F, FORMATTYPE_FLOAT }, 1485 { GL_RGBA32I, FORMATTYPE_INT }, 1486 { GL_RGBA32UI, FORMATTYPE_UINT }, 1487 { GL_RGBA16F, FORMATTYPE_FLOAT }, 1488 { GL_RGBA16I, FORMATTYPE_INT }, 1489 { GL_RGBA16UI, FORMATTYPE_UINT }, 1490 { GL_RGB16F, FORMATTYPE_FLOAT }, 1491 { GL_RGBA8, FORMATTYPE_FIXED }, 1492 { GL_RGBA8I, FORMATTYPE_INT }, 1493 { GL_RGBA8UI, FORMATTYPE_UINT }, 1494 { GL_SRGB8_ALPHA8, FORMATTYPE_FIXED }, 1495 { GL_RGB10_A2, FORMATTYPE_FIXED }, 1496 { GL_RGB10_A2UI, FORMATTYPE_UINT }, 1497 { GL_RGBA4, FORMATTYPE_FIXED }, 1498 { GL_RGB5_A1, FORMATTYPE_FIXED }, 1499 { GL_RGB8, FORMATTYPE_FIXED }, 1500 { GL_RGB565, FORMATTYPE_FIXED }, 1501 { GL_R11F_G11F_B10F, FORMATTYPE_FLOAT }, 1502 { GL_RG32F, FORMATTYPE_FLOAT }, 1503 { GL_RG32I, FORMATTYPE_INT }, 1504 { GL_RG32UI, FORMATTYPE_UINT }, 1505 { GL_RG16F, FORMATTYPE_FLOAT }, 1506 { GL_RG16I, FORMATTYPE_INT }, 1507 { GL_RG16UI, FORMATTYPE_UINT }, 1508 { GL_RG8, FORMATTYPE_FLOAT }, 1509 { GL_RG8I, FORMATTYPE_INT }, 1510 { GL_RG8UI, FORMATTYPE_UINT }, 1511 { GL_R32F, FORMATTYPE_FLOAT }, 1512 { GL_R32I, FORMATTYPE_INT }, 1513 { GL_R32UI, FORMATTYPE_UINT }, 1514 { GL_R16F, FORMATTYPE_FLOAT }, 1515 { GL_R16I, FORMATTYPE_INT }, 1516 { GL_R16UI, FORMATTYPE_UINT }, 1517 { GL_R8, FORMATTYPE_FLOAT }, 1518 { GL_R8I, FORMATTYPE_INT }, 1519 { GL_R8UI, FORMATTYPE_UINT } 1520 }; 1521 1522 static const struct 1523 { 1524 deUint32 format; 1525 bool depth; 1526 bool stencil; 1527 } depthStencilFormats[] = 1528 { 1529 { GL_DEPTH_COMPONENT32F, true, false }, 1530 { GL_DEPTH_COMPONENT24, true, false }, 1531 { GL_DEPTH_COMPONENT16, true, false }, 1532 { GL_DEPTH32F_STENCIL8, true, true }, 1533 { GL_DEPTH24_STENCIL8, true, true }, 1534 { GL_STENCIL_INDEX8, false, true } 1535 }; 1536 1537 using namespace FboCases; 1538 1539 // .stencil_clear 1540 tcu::TestCaseGroup* stencilClearGroup = new tcu::TestCaseGroup(m_testCtx, "stencil_clear", "Stencil buffer clears"); 1541 addChild(stencilClearGroup); 1542 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); fmtNdx++) 1543 { 1544 deUint32 colorType = GL_TEXTURE_2D; 1545 deUint32 stencilType = GL_RENDERBUFFER; 1546 deUint32 colorFmt = GL_RGBA8; 1547 1548 if (!depthStencilFormats[fmtNdx].stencil) 1549 continue; 1550 1551 FboConfig config(GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, colorType, colorFmt, stencilType, depthStencilFormats[fmtNdx].format); 1552 stencilClearGroup->addChild(new StencilClearsTest(m_context, config)); 1553 } 1554 1555 // .shared_colorbuffer_clear 1556 tcu::TestCaseGroup* sharedColorbufferClearGroup = new tcu::TestCaseGroup(m_testCtx, "shared_colorbuffer_clear", "Shader colorbuffer clears"); 1557 addChild(sharedColorbufferClearGroup); 1558 for (int colorFmtNdx = 0; colorFmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); colorFmtNdx++) 1559 { 1560 // Clearing of integer buffers is undefined. 1561 if (colorFormats[colorFmtNdx].type == FORMATTYPE_INT || colorFormats[colorFmtNdx].type == FORMATTYPE_UINT) 1562 continue; 1563 1564 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++) 1565 { 1566 FboConfig config(GL_COLOR_BUFFER_BIT, objectTypes[typeNdx], colorFormats[colorFmtNdx].format, GL_NONE, GL_NONE); 1567 sharedColorbufferClearGroup->addChild(new SharedColorbufferClearsTest(m_context, config)); 1568 } 1569 } 1570 1571 // .shared_colorbuffer 1572 tcu::TestCaseGroup* sharedColorbufferGroup = new tcu::TestCaseGroup(m_testCtx, "shared_colorbuffer", "Shared colorbuffer tests"); 1573 addChild(sharedColorbufferGroup); 1574 for (int colorFmtNdx = 0; colorFmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); colorFmtNdx++) 1575 { 1576 deUint32 depthStencilType = GL_RENDERBUFFER; 1577 deUint32 depthStencilFormat = GL_DEPTH24_STENCIL8; 1578 1579 // Blending with integer buffers and fp32 targets is not supported. 1580 if (colorFormats[colorFmtNdx].type == FORMATTYPE_INT || 1581 colorFormats[colorFmtNdx].type == FORMATTYPE_UINT || 1582 colorFormats[colorFmtNdx].format == GL_RGBA32F || 1583 colorFormats[colorFmtNdx].format == GL_RGB32F || 1584 colorFormats[colorFmtNdx].format == GL_RG32F || 1585 colorFormats[colorFmtNdx].format == GL_R32F) 1586 continue; 1587 1588 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++) 1589 { 1590 FboConfig colorOnlyConfig (GL_COLOR_BUFFER_BIT, objectTypes[typeNdx], colorFormats[colorFmtNdx].format, GL_NONE, GL_NONE); 1591 FboConfig colorDepthConfig (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT, objectTypes[typeNdx], colorFormats[colorFmtNdx].format, depthStencilType, depthStencilFormat); 1592 FboConfig colorDepthStencilConfig (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, objectTypes[typeNdx], colorFormats[colorFmtNdx].format, depthStencilType, depthStencilFormat); 1593 1594 sharedColorbufferGroup->addChild(new SharedColorbufferTest(m_context, colorOnlyConfig)); 1595 sharedColorbufferGroup->addChild(new SharedColorbufferTest(m_context, colorDepthConfig)); 1596 sharedColorbufferGroup->addChild(new SharedColorbufferTest(m_context, colorDepthStencilConfig)); 1597 } 1598 } 1599 1600 // .shared_depth_stencil 1601 tcu::TestCaseGroup* sharedDepthStencilGroup = new tcu::TestCaseGroup(m_testCtx, "shared_depth_stencil", "Shared depth and stencil buffers"); 1602 addChild(sharedDepthStencilGroup); 1603 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); fmtNdx++) 1604 { 1605 deUint32 colorType = GL_TEXTURE_2D; 1606 deUint32 colorFmt = GL_RGBA8; 1607 bool depth = depthStencilFormats[fmtNdx].depth; 1608 bool stencil = depthStencilFormats[fmtNdx].stencil; 1609 1610 if (!depth) 1611 continue; // Not verified. 1612 1613 // Depth and stencil: both rbo and textures 1614 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++) 1615 { 1616 FboConfig config(GL_COLOR_BUFFER_BIT|(depth ? GL_DEPTH_BUFFER_BIT : 0)|(stencil ? GL_STENCIL_BUFFER_BIT : 0), colorType, colorFmt, objectTypes[typeNdx], depthStencilFormats[fmtNdx].format); 1617 sharedDepthStencilGroup->addChild(new SharedDepthStencilTest(m_context, config)); 1618 } 1619 } 1620 1621 // .resize 1622 tcu::TestCaseGroup* resizeGroup = new tcu::TestCaseGroup(m_testCtx, "resize", "FBO resize tests"); 1623 addChild(resizeGroup); 1624 for (int colorFmtNdx = 0; colorFmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); colorFmtNdx++) 1625 { 1626 deUint32 colorFormat = colorFormats[colorFmtNdx].format; 1627 1628 // Color-only. 1629 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++) 1630 { 1631 FboConfig config(GL_COLOR_BUFFER_BIT, objectTypes[typeNdx], colorFormat, GL_NONE, GL_NONE); 1632 resizeGroup->addChild(new ResizeTest(m_context, config)); 1633 } 1634 1635 // For selected color formats tests depth & stencil variants. 1636 if (colorFormat == GL_RGBA8 || colorFormat == GL_RGBA16F) 1637 { 1638 for (int depthStencilFmtNdx = 0; depthStencilFmtNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); depthStencilFmtNdx++) 1639 { 1640 deUint32 colorType = GL_TEXTURE_2D; 1641 bool depth = depthStencilFormats[depthStencilFmtNdx].depth; 1642 bool stencil = depthStencilFormats[depthStencilFmtNdx].stencil; 1643 1644 // Depth and stencil: both rbo and textures 1645 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++) 1646 { 1647 if (!depth && objectTypes[typeNdx] != GL_RENDERBUFFER) 1648 continue; // Not supported. 1649 1650 FboConfig config(GL_COLOR_BUFFER_BIT|(depth ? GL_DEPTH_BUFFER_BIT : 0)|(stencil ? GL_STENCIL_BUFFER_BIT : 0), 1651 colorType, colorFormat, 1652 objectTypes[typeNdx], depthStencilFormats[depthStencilFmtNdx].format); 1653 resizeGroup->addChild(new ResizeTest(m_context, config)); 1654 } 1655 } 1656 } 1657 } 1658 1659 // .recreate_color 1660 tcu::TestCaseGroup* recreateColorGroup = new tcu::TestCaseGroup(m_testCtx, "recreate_color", "Recreate colorbuffer tests"); 1661 addChild(recreateColorGroup); 1662 for (int colorFmtNdx = 0; colorFmtNdx < DE_LENGTH_OF_ARRAY(colorFormats); colorFmtNdx++) 1663 { 1664 deUint32 colorFormat = colorFormats[colorFmtNdx].format; 1665 deUint32 depthStencilFormat = GL_DEPTH24_STENCIL8; 1666 deUint32 depthStencilType = GL_RENDERBUFFER; 1667 1668 // Color-only. 1669 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++) 1670 { 1671 FboConfig config(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, objectTypes[typeNdx], colorFormat, depthStencilType, depthStencilFormat); 1672 recreateColorGroup->addChild(new RecreateBuffersTest(m_context, config, GL_COLOR_BUFFER_BIT, true /* rebind */)); 1673 } 1674 } 1675 1676 // .recreate_depth_stencil 1677 tcu::TestCaseGroup* recreateDepthStencilGroup = new tcu::TestCaseGroup(m_testCtx, "recreate_depth_stencil", "Recreate depth and stencil buffers"); 1678 addChild(recreateDepthStencilGroup); 1679 for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); fmtNdx++) 1680 { 1681 deUint32 colorType = GL_TEXTURE_2D; 1682 deUint32 colorFmt = GL_RGBA8; 1683 bool depth = depthStencilFormats[fmtNdx].depth; 1684 bool stencil = depthStencilFormats[fmtNdx].stencil; 1685 1686 // Depth and stencil: both rbo and textures 1687 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++) 1688 { 1689 if (!depth && objectTypes[typeNdx] != GL_RENDERBUFFER) 1690 continue; 1691 1692 FboConfig config(GL_COLOR_BUFFER_BIT|(depth ? GL_DEPTH_BUFFER_BIT : 0)|(stencil ? GL_STENCIL_BUFFER_BIT : 0), colorType, colorFmt, objectTypes[typeNdx], depthStencilFormats[fmtNdx].format); 1693 recreateDepthStencilGroup->addChild(new RecreateBuffersTest(m_context, config, (depth ? GL_DEPTH_BUFFER_BIT : 0)|(stencil ? GL_STENCIL_BUFFER_BIT : 0), true /* rebind */)); 1694 } 1695 } 1696 } 1697 1698 } // Functional 1699 } // gles3 1700 } // deqp 1701