1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.0 Module
3 * -------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Framebuffer Object Tests.
22 *//*--------------------------------------------------------------------*/
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"
39 #include "glwDefs.hpp"
40 #include "glwEnums.hpp"
64 using namespace FboTestUtil;
69 FboConfig (deUint32 buffers_, deUint32 colorType_, deUint32 colorFormat_, deUint32 depthStencilType_, deUint32 depthStencilFormat_, int width_ = 0, int height_ = 0, int samples_ = 0)
71 , colorType (colorType_)
72 , colorFormat (colorFormat_)
73 , depthStencilType (depthStencilType_)
74 , depthStencilFormat (depthStencilFormat_)
84 , colorFormat (GL_NONE)
85 , depthStencilType (GL_NONE)
86 , depthStencilFormat (GL_NONE)
93 std::string getName (void) const;
95 deUint32 buffers; //!< Buffer bit mask (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|...)
97 GLenum colorType; //!< GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, GL_RENDERBUFFER
98 GLenum colorFormat; //!< Internal format for color buffer texture or renderbuffer
100 GLenum depthStencilType;
101 GLenum depthStencilFormat;
108 static const char* getTypeName (GLenum type)
112 case GL_TEXTURE_2D: return "tex2d";
113 case GL_RENDERBUFFER: return "rbo";
115 TCU_FAIL("Unknown type");
119 std::string FboConfig::getName (void) const
121 std::ostringstream name;
123 DE_ASSERT(buffers & GL_COLOR_BUFFER_BIT);
124 name << getTypeName(colorType) << "_" << getFormatName(colorFormat);
126 if (buffers & GL_DEPTH_BUFFER_BIT)
128 if (buffers & GL_STENCIL_BUFFER_BIT)
131 if (buffers & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT))
132 name << "_" << getTypeName(depthStencilType) << "_" << getFormatName(depthStencilFormat);
140 Framebuffer (sglr::Context& context, const FboConfig& config, int width, int height, deUint32 fbo = 0, deUint32 colorBuffer = 0, deUint32 depthStencilBuffer = 0);
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; }
148 void checkCompleteness (void);
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);
156 sglr::Context& m_context;
157 deUint32 m_framebuffer;
158 deUint32 m_colorBuffer;
159 deUint32 m_depthStencilBuffer;
162 static std::vector<std::string> getEnablingExtensions (deUint32 format)
164 std::vector<std::string> out;
169 out.push_back("GL_EXT_color_buffer_half_float");
175 out.push_back("GL_EXT_color_buffer_half_float");
179 case GL_R11F_G11F_B10F:
182 out.push_back("GL_EXT_color_buffer_float");
191 static bool isExtensionSupported (sglr::Context& context, const char* name)
193 std::istringstream extensions(context.getString(GL_EXTENSIONS));
194 std::string extension;
196 while (std::getline(extensions, extension, ' '))
198 if (extension == name)
205 static bool isAnyExtensionSupported (sglr::Context& context, const std::vector<std::string>& requiredExts)
207 if (requiredExts.empty())
210 for (std::vector<std::string>::const_iterator iter = requiredExts.begin(); iter != requiredExts.end(); iter++)
212 const std::string& extension = *iter;
214 if (isExtensionSupported(context, extension.c_str()))
222 static std::string join (const std::vector<T>& list, const std::string& sep)
224 std::ostringstream out;
226 for (typename std::vector<T>::const_iterator iter = list.begin(); iter != list.end(); iter++)
228 if (iter != list.begin())
236 static void checkColorFormatSupport (sglr::Context& context, deUint32 sizedFormat)
238 const std::vector<std::string> requiredExts = getEnablingExtensions(sizedFormat);
240 if (!isAnyExtensionSupported(context, requiredExts))
242 std::string errMsg = "Format not supported, requires "
243 + ((requiredExts.size() == 1) ? requiredExts[0] : " one of the following: " + join(requiredExts, ", "));
245 throw tcu::NotSupportedError(errMsg);
249 Framebuffer::Framebuffer (sglr::Context& context, const FboConfig& config, int width, int height, deUint32 fbo, deUint32 colorBufferName, deUint32 depthStencilBufferName)
251 , m_context (context)
252 , m_framebuffer (fbo)
254 , m_depthStencilBuffer (0)
256 // Verify that color format is supported
257 checkColorFormatSupport(context, config.colorFormat);
259 if (m_framebuffer == 0)
260 context.genFramebuffers(1, &m_framebuffer);
261 context.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
263 if (m_config.buffers & (GL_COLOR_BUFFER_BIT))
265 switch (m_config.colorType)
268 m_colorBuffer = createTex2D(colorBufferName, m_config.colorFormat, width, height);
269 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorBuffer, 0);
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);
278 TCU_FAIL("Unsupported type");
282 if (m_config.buffers & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT))
284 switch (m_config.depthStencilType)
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;
289 TCU_FAIL("Unsupported type");
293 for (int ndx = 0; ndx < 2; ndx++)
295 deUint32 bit = ndx ? GL_STENCIL_BUFFER_BIT : GL_DEPTH_BUFFER_BIT;
296 deUint32 point = ndx ? GL_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
298 if ((m_config.buffers & bit) == 0)
299 continue; /* Not used. */
301 switch (m_config.depthStencilType)
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;
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__);
314 context.bindFramebuffer(GL_FRAMEBUFFER, 0);
317 Framebuffer::~Framebuffer (void)
319 m_context.deleteFramebuffers(1, &m_framebuffer);
320 destroyBuffer(m_colorBuffer, m_config.colorType);
321 destroyBuffer(m_depthStencilBuffer, m_config.depthStencilType);
324 void Framebuffer::checkCompleteness (void)
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__);
333 deUint32 Framebuffer::createTex2D (deUint32 name, GLenum format, int width, int height)
336 m_context.genTextures(1, &name);
338 m_context.bindTexture(GL_TEXTURE_2D, name);
339 m_context.texImage2D(GL_TEXTURE_2D, 0, format, width, height);
341 if (!deIsPowerOfTwo32(width) || !deIsPowerOfTwo32(height))
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);
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);
354 deUint32 Framebuffer::createRbo (deUint32 name, GLenum format, int width, int height)
357 m_context.genRenderbuffers(1, &name);
359 m_context.bindRenderbuffer(GL_RENDERBUFFER, name);
360 m_context.renderbufferStorage(GL_RENDERBUFFER, format, width, height);
365 void Framebuffer::destroyBuffer (deUint32 name, GLenum type)
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);
372 DE_ASSERT(type == GL_NONE);
375 static void createMetaballsTex2D (sglr::Context& context, deUint32 name, GLenum format, GLenum dataType, int width, int height)
377 tcu::TextureFormat texFormat = glu::mapGLTransferFormat(format, dataType);
378 tcu::TextureLevel level (texFormat, width, height);
380 tcu::fillWithMetaballs(level.getAccess(), 5, name ^ width ^ height);
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);
387 static void createQuadsTex2D (sglr::Context& context, deUint32 name, GLenum format, GLenum dataType, int width, int height)
389 tcu::TextureFormat texFormat = glu::mapGLTransferFormat(format, dataType);
390 tcu::TextureLevel level (texFormat, width, height);
392 tcu::fillWithRGBAQuads(level.getAccess());
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);
399 class FboRenderCase : public TestCase
402 FboRenderCase (Context& context, const char* name, const char* description, const FboConfig& config);
403 virtual ~FboRenderCase (void) {}
405 virtual IterateResult iterate (void);
406 virtual void render (sglr::Context& fboContext, Surface& dst) = DE_NULL;
408 bool compare (const tcu::Surface& reference, const tcu::Surface& result);
411 const FboConfig m_config;
414 FboRenderCase::FboRenderCase (Context& context, const char* name, const char* description, const FboConfig& config)
415 : TestCase (context, name, description)
420 TestCase::IterateResult FboRenderCase::iterate (void)
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;
428 // Position & size for context
430 deRandom_init(&rnd, deStringHash(getName()));
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;
439 tcu::Surface gles3Frame (width, height);
440 tcu::Surface refFrame (width, height);
444 // Render using GLES3
447 sglr::GLContext context(renderCtx, log, sglr::GLCONTEXT_LOG_CALLS, tcu::IVec4(x, y, width, height));
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);
452 render(context, gles3Frame); // Call actual render func
453 gles3Error = context.getError();
455 catch (const FboIncompleteException& e)
457 if (e.getReason() == GL_FRAMEBUFFER_UNSUPPORTED)
459 // Mark test case as unsupported
461 m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Not supported");
465 throw; // Propagate error
468 // Render reference image
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());
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);
476 render(context, refFrame);
477 refError = context.getError();
480 // Compare error codes
481 bool errorCodesOk = (gles3Error == refError);
485 log << tcu::TestLog::Message << "Error code mismatch: got " << glu::getErrorStr(gles3Error) << ", expected " << glu::getErrorStr(refError) << tcu::TestLog::EndMessage;
486 failReason = "Got unexpected error";
490 bool imagesOk = compare(refFrame, gles3Frame);
492 if (!imagesOk && !failReason)
493 failReason = "Image comparison failed";
496 bool isOk = errorCodesOk && imagesOk;
497 m_testCtx.setTestResult(isOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
498 isOk ? "Pass" : failReason);
503 bool FboRenderCase::compare (const tcu::Surface& reference, const tcu::Surface& result)
505 const tcu::RGBA threshold (tcu::max(getFormatThreshold(m_config.colorFormat), tcu::RGBA(12, 12, 12, 12)));
507 return tcu::bilinearCompare(m_testCtx.getLog(), "ComparisonResult", "Image comparison result", reference.getAccess(), result.getAccess(), threshold, tcu::COMPARE_LOG_RESULT);
513 class StencilClearsTest : public FboRenderCase
516 StencilClearsTest (Context& context, const FboConfig& config);
517 virtual ~StencilClearsTest (void) {};
519 void render (sglr::Context& context, Surface& dst);
522 StencilClearsTest::StencilClearsTest (Context& context, const FboConfig& config)
523 : FboRenderCase (context, config.getName().c_str(), "Stencil clears", config)
527 void StencilClearsTest::render (sglr::Context& context, Surface& dst)
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;
536 Texture2DShader texToFboShader (DataTypes() << glu::TYPE_SAMPLER_2D, fboOutputType);
537 Texture2DShader texFromFboShader (DataTypes() << fboSamplerType, glu::TYPE_FLOAT_VEC4);
539 deUint32 texToFboShaderID = context.createProgram(&texToFboShader);
540 deUint32 texFromFboShaderID = context.createProgram(&texFromFboShader);
542 deUint32 metaballsTex = 1;
543 deUint32 quadsTex = 2;
547 texToFboShader.setOutScaleBias(fboOutScale, fboOutBias);
548 texFromFboShader.setTexScaleBias(0, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias);
550 createQuadsTex2D(context, quadsTex, GL_RGBA, GL_UNSIGNED_BYTE, width, height);
551 createMetaballsTex2D(context, metaballsTex, GL_RGBA, GL_UNSIGNED_BYTE, width, height);
553 Framebuffer fbo(context, m_config, width, height);
554 fbo.checkCompleteness();
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);
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);
572 // Draw 2 textures with stecil tests
573 context.enable(GL_STENCIL_TEST);
575 context.bindTexture(GL_TEXTURE_2D, quadsTex);
576 context.stencilFunc(GL_EQUAL, 1, 0xffu);
578 texToFboShader.setUniforms(context, texToFboShaderID);
579 sglr::drawQuad(context, texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f));
581 context.bindTexture(GL_TEXTURE_2D, metaballsTex);
582 context.stencilFunc(GL_EQUAL, 2, 0xffu);
584 texToFboShader.setUniforms(context, texToFboShaderID);
585 sglr::drawQuad(context, texToFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f));
587 context.disable(GL_STENCIL_TEST);
589 if (fbo.getConfig().colorType == GL_TEXTURE_2D)
591 context.bindFramebuffer(GL_FRAMEBUFFER, 0);
592 context.bindTexture(GL_TEXTURE_2D, fbo.getColorBuffer());
593 context.viewport(0, 0, context.getWidth(), context.getHeight());
595 texFromFboShader.setUniforms(context, texFromFboShaderID);
596 sglr::drawQuad(context, texFromFboShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f));
598 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
601 readPixels(context, dst, 0, 0, width, height, colorFormat, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias);
604 class SharedColorbufferTest : public FboRenderCase
607 SharedColorbufferTest (Context& context, const FboConfig& config);
608 virtual ~SharedColorbufferTest (void) {};
610 void render (sglr::Context& context, Surface& dst);
613 SharedColorbufferTest::SharedColorbufferTest (Context& context, const FboConfig& config)
614 : FboRenderCase (context, config.getName().c_str(), "Shared colorbuffer", config)
618 void SharedColorbufferTest::render (sglr::Context& context, Surface& dst)
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);
627 deUint32 quadsTex = 1;
628 deUint32 metaballsTex = 2;
629 bool stencil = (m_config.buffers & GL_STENCIL_BUFFER_BIT) != 0;
631 context.disable(GL_DITHER);
634 createQuadsTex2D(context, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);
635 createMetaballsTex2D(context, metaballsTex, GL_RGBA, GL_UNSIGNED_BYTE, 64, 64);
637 context.viewport(0, 0, width, height);
640 Framebuffer fboA(context, m_config, width, height);
641 fboA.checkCompleteness();
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);
650 // Attach color buffer from fbo A
651 context.bindFramebuffer(GL_FRAMEBUFFER, fboB.getFramebuffer());
652 switch (m_config.colorType)
655 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboA.getColorBuffer(), 0);
658 case GL_RENDERBUFFER:
659 context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fboA.getColorBuffer());
666 // Clear depth and stencil in fbo B
667 context.clear(GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
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);
677 // Stencil to 1 in fbo A
678 context.clearStencil(1);
679 context.clear(GL_STENCIL_BUFFER_BIT);
682 texShader.setUniforms(context, texShaderID);
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);
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));
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);
703 flatShader.setColor(context, flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
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);
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);
720 if (fboA.getConfig().colorType == GL_TEXTURE_2D)
722 texShader.setUniforms(context, texShaderID);
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());
731 readPixels(context, dst, 0, 0, width, height, glu::mapGLInternalFormat(fboA.getConfig().colorFormat), Vec4(1.0f), Vec4(0.0f));
734 class SharedColorbufferClearsTest : public FboRenderCase
737 SharedColorbufferClearsTest (Context& context, const FboConfig& config);
738 virtual ~SharedColorbufferClearsTest (void) {}
740 void render (sglr::Context& context, Surface& dst);
743 SharedColorbufferClearsTest::SharedColorbufferClearsTest (Context& context, const FboConfig& config)
744 : FboRenderCase (context, config.getName().c_str(), "Shared colorbuffer clears", config)
748 void SharedColorbufferClearsTest::render (sglr::Context& context, Surface& dst)
750 tcu::TextureFormat colorFormat = glu::mapGLInternalFormat(m_config.colorFormat);
751 glu::DataType fboSamplerType = glu::getSampler2DType(colorFormat);
754 deUint32 colorbuffer = 1;
756 // Check for format support.
757 checkColorFormatSupport(context, m_config.colorFormat);
759 // Single colorbuffer
760 if (m_config.colorType == GL_TEXTURE_2D)
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);
769 DE_ASSERT(m_config.colorType == GL_RENDERBUFFER);
770 context.bindRenderbuffer(GL_RENDERBUFFER, colorbuffer);
771 context.renderbufferStorage(GL_RENDERBUFFER, m_config.colorFormat, width, height);
774 // Multiple framebuffers sharing the colorbuffer
775 for (int fbo = 1; fbo <= 3; fbo++)
777 context.bindFramebuffer(GL_FRAMEBUFFER, fbo);
779 if (m_config.colorType == GL_TEXTURE_2D)
780 context.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuffer, 0);
782 context.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuffer);
785 context.bindFramebuffer(GL_FRAMEBUFFER, 1);
787 // Check completeness
789 GLenum status = context.checkFramebufferStatus(GL_FRAMEBUFFER);
790 if (status != GL_FRAMEBUFFER_COMPLETE)
791 throw FboIncompleteException(status, __FILE__, __LINE__);
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);
799 context.enable(GL_SCISSOR_TEST);
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);
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);
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);
819 context.disable(GL_SCISSOR_TEST);
821 if (m_config.colorType == GL_TEXTURE_2D)
823 Texture2DShader shader(DataTypes() << fboSamplerType, glu::TYPE_FLOAT_VEC4);
824 deUint32 shaderID = context.createProgram(&shader);
826 shader.setUniforms(context, shaderID);
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());
834 readPixels(context, dst, 0, 0, width, height, colorFormat, Vec4(1.0f), Vec4(0.0f));
837 class SharedDepthStencilTest : public FboRenderCase
840 SharedDepthStencilTest (Context& context, const FboConfig& config);
841 virtual ~SharedDepthStencilTest (void) {};
843 static bool isConfigSupported (const FboConfig& config);
844 void render (sglr::Context& context, Surface& dst);
847 SharedDepthStencilTest::SharedDepthStencilTest (Context& context, const FboConfig& config)
848 : FboRenderCase (context, config.getName().c_str(), "Shared depth/stencilbuffer", config)
852 bool SharedDepthStencilTest::isConfigSupported (const FboConfig& config)
854 return (config.buffers & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) != 0;
857 void SharedDepthStencilTest::render (sglr::Context& context, Surface& dst)
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);
865 // bool depth = (m_config.buffers & GL_DEPTH_BUFFER_BIT) != 0;
866 bool stencil = (m_config.buffers & GL_STENCIL_BUFFER_BIT) != 0;
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);
874 context.viewport(0, 0, width, height);
877 Framebuffer fboA(context, m_config, width, height);
878 fboA.checkCompleteness();
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);
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++)
891 deUint32 bit = ndx ? GL_STENCIL_BUFFER_BIT : GL_DEPTH_BUFFER_BIT;
892 deUint32 point = ndx ? GL_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT;
894 if ((m_config.buffers & bit) == 0)
897 switch (m_config.depthStencilType)
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;
902 TCU_FAIL("Not implemented");
907 texShader.setUniforms(context, texShaderID);
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);
914 context.enable(GL_DEPTH_TEST);
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));
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);
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));
936 context.disable(GL_DEPTH_TEST);
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);
949 if (m_config.colorType == GL_TEXTURE_2D)
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));
959 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
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));
969 class TexSubImageAfterRenderTest : public FboRenderCase
972 TexSubImageAfterRenderTest (Context& context, const FboConfig& config);
973 virtual ~TexSubImageAfterRenderTest (void) {}
975 void render (sglr::Context& context, Surface& dst);
978 TexSubImageAfterRenderTest::TexSubImageAfterRenderTest (Context& context, const FboConfig& config)
979 : FboRenderCase(context, (string("after_render_") + config.getName()).c_str(), "TexSubImage after rendering to texture", config)
983 void TexSubImageAfterRenderTest::render (sglr::Context& context, Surface& dst)
985 using sglr::TexturedQuadOp;
989 Surface fourQuads(Surface::PIXELFORMAT_RGB, 64, 64);
990 tcu::SurfaceUtil::fillWithFourQuads(fourQuads);
992 Surface metaballs(isRGBA ? Surface::PIXELFORMAT_RGBA : Surface::PIXELFORMAT_RGB, 64, 64);
993 tcu::SurfaceUtil::fillWithMetaballs(metaballs, 5, 3);
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);
1000 context.bindFramebuffer(GL_FRAMEBUFFER, 1);
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);
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));
1013 // Update texture using TexSubImage2D
1014 context.bindTexture(GL_TEXTURE_2D, fboTex);
1015 context.texSubImage2D(GL_TEXTURE_2D, 0, 32, 32, metaballs);
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());
1024 class TexSubImageBetweenRenderTest : public FboRenderCase
1027 TexSubImageBetweenRenderTest (Context& context, const FboConfig& config);
1028 virtual ~TexSubImageBetweenRenderTest (void) {}
1030 void render (sglr::Context& context, Surface& dst);
1033 TexSubImageBetweenRenderTest::TexSubImageBetweenRenderTest (Context& context, const FboConfig& config)
1034 : FboRenderCase(context, (string("between_render_") + config.getName()).c_str(), "TexSubImage between rendering calls", config)
1038 void TexSubImageBetweenRenderTest::render (sglr::Context& context, Surface& dst)
1040 using sglr::TexturedQuadOp;
1041 using sglr::BlendTextureOp;
1045 Surface fourQuads(Surface::PIXELFORMAT_RGB, 64, 64);
1046 tcu::SurfaceUtil::fillWithFourQuads(fourQuads);
1048 Surface metaballs(isRGBA ? Surface::PIXELFORMAT_RGBA : Surface::PIXELFORMAT_RGB, 64, 64);
1049 tcu::SurfaceUtil::fillWithMetaballs(metaballs, 5, 3);
1051 Surface metaballs2(Surface::PIXELFORMAT_RGBA, 64, 64);
1052 tcu::SurfaceUtil::fillWithMetaballs(metaballs2, 5, 4);
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);
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);
1064 context.bindFramebuffer(GL_FRAMEBUFFER, 1);
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);
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));
1077 // Update texture using TexSubImage2D
1078 context.bindTexture(GL_TEXTURE_2D, fboTex);
1079 context.texSubImage2D(GL_TEXTURE_2D, 0, 32, 32, metaballs);
1081 // Render again to fbo
1082 context.bindTexture(GL_TEXTURE_2D, metaballsTex);
1083 context.draw(BlendTextureOp(0));
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));
1091 context.readPixels(dst, 0, 0, context.getWidth(), context.getHeight());
1095 class ResizeTest : public FboRenderCase
1098 ResizeTest (Context& context, const FboConfig& config);
1099 virtual ~ResizeTest (void) {}
1101 void render (sglr::Context& context, Surface& dst);
1104 ResizeTest::ResizeTest (Context& context, const FboConfig& config)
1105 : FboRenderCase (context, config.getName().c_str(), "Resize framebuffer", config)
1109 void ResizeTest::render (sglr::Context& context, Surface& dst)
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;
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);
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;
1134 texToFboShader.setOutScaleBias(fboOutScale, fboOutBias);
1135 texFromFboShader.setTexScaleBias(0, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias);
1137 createQuadsTex2D(context, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);
1138 createMetaballsTex2D(context, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 32, 32);
1140 Framebuffer fbo(context, m_config, initialWidth, initialHeight);
1141 fbo.checkCompleteness();
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);
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));
1156 if (fbo.getConfig().colorType == GL_TEXTURE_2D)
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));
1165 context.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer());
1169 switch (fbo.getConfig().colorType)
1172 context.bindTexture(GL_TEXTURE_2D, fbo.getColorBuffer());
1173 context.texImage2D(GL_TEXTURE_2D, 0, fbo.getConfig().colorFormat, newWidth, newHeight);
1176 case GL_RENDERBUFFER:
1177 context.bindRenderbuffer(GL_RENDERBUFFER, fbo.getColorBuffer());
1178 context.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().colorFormat, newWidth, newHeight);
1182 DE_ASSERT(DE_FALSE);
1185 if (depth || stencil)
1187 switch (fbo.getConfig().depthStencilType)
1190 context.bindTexture(GL_TEXTURE_2D, fbo.getDepthStencilBuffer());
1191 context.texImage2D(GL_TEXTURE_2D, 0, fbo.getConfig().depthStencilFormat, newWidth, newHeight);
1194 case GL_RENDERBUFFER:
1195 context.bindRenderbuffer(GL_RENDERBUFFER, fbo.getDepthStencilBuffer());
1196 context.renderbufferStorage(GL_RENDERBUFFER, fbo.getConfig().depthStencilFormat, newWidth, newHeight);
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);
1209 context.enable(GL_DEPTH_TEST);
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));
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));
1217 context.disable(GL_DEPTH_TEST);
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);
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);
1233 if (m_config.colorType == GL_TEXTURE_2D)
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());
1242 readPixels(context, dst, 0, 0, newWidth, newHeight, colorFormat, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias);
1245 class RecreateBuffersTest : public FboRenderCase
1248 RecreateBuffersTest (Context& context, const FboConfig& config, deUint32 buffers, bool rebind);
1249 virtual ~RecreateBuffersTest (void) {}
1251 void render (sglr::Context& context, Surface& dst);
1258 RecreateBuffersTest::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)
1265 void RecreateBuffersTest::render (sglr::Context& ctx, Surface& dst)
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;
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);
1283 deUint32 metaballsTex = 1;
1284 deUint32 quadsTex = 2;
1285 bool stencil = (m_config.buffers & GL_STENCIL_BUFFER_BIT) != 0;
1287 createQuadsTex2D(ctx, quadsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);
1288 createMetaballsTex2D(ctx, metaballsTex, GL_RGB, GL_UNSIGNED_BYTE, 64, 64);
1290 Framebuffer fbo(ctx, m_config, width, height);
1291 fbo.checkCompleteness();
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);
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);
1306 ctx.enable(GL_DEPTH_TEST);
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));
1311 ctx.disable(GL_DEPTH_TEST);
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);
1324 ctx.bindFramebuffer(GL_FRAMEBUFFER, 0);
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)));
1330 for (int ndx = 0; ndx < 2; ndx++)
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();
1341 if ((m_buffers & bit) == 0)
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);
1354 case GL_RENDERBUFFER:
1355 ctx.deleteRenderbuffers(1, &buf);
1356 ctx.bindRenderbuffer(GL_RENDERBUFFER, buf);
1357 ctx.renderbufferStorage(GL_RENDERBUFFER, format, width, height);
1368 for (int ndx = 0; ndx < 3; ndx++)
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();
1381 if ((m_buffers & bit) == 0)
1387 ctx.framebufferTexture2D(GL_FRAMEBUFFER, point, GL_TEXTURE_2D, buf, 0);
1390 case GL_RENDERBUFFER:
1391 ctx.framebufferRenderbuffer(GL_FRAMEBUFFER, point, GL_RENDERBUFFER, buf);
1401 ctx.bindFramebuffer(GL_FRAMEBUFFER, fbo.getFramebuffer());
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)
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));
1411 ctx.enable(GL_DEPTH_TEST);
1415 // \note Stencil test enabled only if we have stencil buffer
1416 ctx.enable(GL_STENCIL_TEST);
1417 ctx.stencilFunc(GL_EQUAL, 0, 0xffu);
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));
1422 ctx.disable(GL_STENCIL_TEST);
1424 ctx.disable(GL_DEPTH_TEST);
1426 if (fbo.getConfig().colorType == GL_TEXTURE_2D)
1429 ctx.bindFramebuffer(GL_FRAMEBUFFER, 0);
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));
1437 ctx.readPixels(dst, 0, 0, ctx.getWidth(), ctx.getHeight());
1442 readPixels(ctx, dst, 0, 0, width, height, colorFormat, fboRangeInfo.lookupScale, fboRangeInfo.lookupBias);
1448 FboRenderTestGroup::FboRenderTestGroup (Context& context)
1449 : TestCaseGroup(context, "render", "Rendering Tests")
1453 FboRenderTestGroup::~FboRenderTestGroup (void)
1457 void FboRenderTestGroup::init (void)
1459 static const deUint32 objectTypes[] =
1467 FORMATTYPE_FLOAT = 0,
1475 // Required by specification.
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 }
1525 } depthStencilFormats[] =
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 }
1535 using namespace FboCases;
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++)
1542 deUint32 colorType = GL_TEXTURE_2D;
1543 deUint32 stencilType = GL_RENDERBUFFER;
1544 deUint32 colorFmt = GL_RGBA8;
1546 if (!depthStencilFormats[fmtNdx].stencil)
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));
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++)
1558 // Clearing of integer buffers is undefined.
1559 if (colorFormats[colorFmtNdx].type == FORMATTYPE_INT || colorFormats[colorFmtNdx].type == FORMATTYPE_UINT)
1562 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++)
1564 FboConfig config(GL_COLOR_BUFFER_BIT, objectTypes[typeNdx], colorFormats[colorFmtNdx].format, GL_NONE, GL_NONE);
1565 sharedColorbufferClearGroup->addChild(new SharedColorbufferClearsTest(m_context, config));
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++)
1574 deUint32 depthStencilType = GL_RENDERBUFFER;
1575 deUint32 depthStencilFormat = GL_DEPTH24_STENCIL8;
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)
1586 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++)
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);
1592 sharedColorbufferGroup->addChild(new SharedColorbufferTest(m_context, colorOnlyConfig));
1593 sharedColorbufferGroup->addChild(new SharedColorbufferTest(m_context, colorDepthConfig));
1594 sharedColorbufferGroup->addChild(new SharedColorbufferTest(m_context, colorDepthStencilConfig));
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++)
1603 deUint32 colorType = GL_TEXTURE_2D;
1604 deUint32 colorFmt = GL_RGBA8;
1605 bool depth = depthStencilFormats[fmtNdx].depth;
1606 bool stencil = depthStencilFormats[fmtNdx].stencil;
1609 continue; // Not verified.
1611 // Depth and stencil: both rbo and textures
1612 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++)
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));
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++)
1624 deUint32 colorFormat = colorFormats[colorFmtNdx].format;
1627 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++)
1629 FboConfig config(GL_COLOR_BUFFER_BIT, objectTypes[typeNdx], colorFormat, GL_NONE, GL_NONE);
1630 resizeGroup->addChild(new ResizeTest(m_context, config));
1633 // For selected color formats tests depth & stencil variants.
1634 if (colorFormat == GL_RGBA8 || colorFormat == GL_RGBA16F)
1636 for (int depthStencilFmtNdx = 0; depthStencilFmtNdx < DE_LENGTH_OF_ARRAY(depthStencilFormats); depthStencilFmtNdx++)
1638 deUint32 colorType = GL_TEXTURE_2D;
1639 bool depth = depthStencilFormats[depthStencilFmtNdx].depth;
1640 bool stencil = depthStencilFormats[depthStencilFmtNdx].stencil;
1642 // Depth and stencil: both rbo and textures
1643 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++)
1645 if (!depth && objectTypes[typeNdx] != GL_RENDERBUFFER)
1646 continue; // Not supported.
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));
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++)
1662 deUint32 colorFormat = colorFormats[colorFmtNdx].format;
1663 deUint32 depthStencilFormat = GL_DEPTH24_STENCIL8;
1664 deUint32 depthStencilType = GL_RENDERBUFFER;
1667 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++)
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 */));
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++)
1679 deUint32 colorType = GL_TEXTURE_2D;
1680 deUint32 colorFmt = GL_RGBA8;
1681 bool depth = depthStencilFormats[fmtNdx].depth;
1682 bool stencil = depthStencilFormats[fmtNdx].stencil;
1684 // Depth and stencil: both rbo and textures
1685 for (int typeNdx = 0; typeNdx < DE_LENGTH_OF_ARRAY(objectTypes); typeNdx++)
1687 if (!depth && objectTypes[typeNdx] != GL_RENDERBUFFER)
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 */));