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