Path: blob/main_old/src/tests/gl_tests/ClearTest.cpp
1693 views
//1// Copyright 2015 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56#include "test_utils/ANGLETest.h"78#include "platform/FeaturesVk.h"9#include "test_utils/gl_raii.h"10#include "util/random_utils.h"11#include "util/shader_utils.h"12#include "util/test_utils.h"1314using namespace angle;1516namespace17{18class ClearTestBase : public ANGLETest19{20protected:21ClearTestBase()22{23setWindowWidth(128);24setWindowHeight(128);25setConfigRedBits(8);26setConfigGreenBits(8);27setConfigBlueBits(8);28setConfigAlphaBits(8);29setConfigDepthBits(24);30setConfigStencilBits(8);31}3233void testSetUp() override34{35mFBOs.resize(2, 0);36glGenFramebuffers(2, mFBOs.data());3738ASSERT_GL_NO_ERROR();39}4041void testTearDown() override42{43if (!mFBOs.empty())44{45glDeleteFramebuffers(static_cast<GLsizei>(mFBOs.size()), mFBOs.data());46}4748if (!mTextures.empty())49{50glDeleteTextures(static_cast<GLsizei>(mTextures.size()), mTextures.data());51}52}5354std::vector<GLuint> mFBOs;55std::vector<GLuint> mTextures;56};5758class ClearTest : public ClearTestBase59{};6061class ClearTestES3 : public ClearTestBase62{63protected:64void verifyDepth(float depthValue, uint32_t size)65{66// Use a small shader to verify depth.67ANGLE_GL_PROGRAM(depthTestProgram, essl1_shaders::vs::Passthrough(),68essl1_shaders::fs::Blue());69ANGLE_GL_PROGRAM(depthTestProgramFail, essl1_shaders::vs::Passthrough(),70essl1_shaders::fs::Red());71glEnable(GL_DEPTH_TEST);72glDepthFunc(GL_LESS);73drawQuad(depthTestProgram, essl1_shaders::PositionAttrib(), depthValue * 2 - 1 - 0.01f);74drawQuad(depthTestProgramFail, essl1_shaders::PositionAttrib(), depthValue * 2 - 1 + 0.01f);75glDisable(GL_DEPTH_TEST);76ASSERT_GL_NO_ERROR();7778EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::blue, 1);79EXPECT_PIXEL_COLOR_NEAR(size - 1, 0, GLColor::blue, 1);80EXPECT_PIXEL_COLOR_NEAR(0, size - 1, GLColor::blue, 1);81EXPECT_PIXEL_COLOR_NEAR(size - 1, size - 1, GLColor::blue, 1);82}8384void verifyStencil(uint32_t stencilValue, uint32_t size)85{86// Use another small shader to verify stencil.87ANGLE_GL_PROGRAM(stencilTestProgram, essl1_shaders::vs::Passthrough(),88essl1_shaders::fs::Green());89glEnable(GL_STENCIL_TEST);90glStencilFunc(GL_EQUAL, stencilValue, 0xFF);91drawQuad(stencilTestProgram, essl1_shaders::PositionAttrib(), 0.0f);92glDisable(GL_STENCIL_TEST);93ASSERT_GL_NO_ERROR();9495EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::green, 1);96EXPECT_PIXEL_COLOR_NEAR(size - 1, 0, GLColor::green, 1);97EXPECT_PIXEL_COLOR_NEAR(0, size - 1, GLColor::green, 1);98EXPECT_PIXEL_COLOR_NEAR(size - 1, size - 1, GLColor::green, 1);99}100};101102class ClearTestRGB : public ANGLETest103{104protected:105ClearTestRGB()106{107setWindowWidth(128);108setWindowHeight(128);109setConfigRedBits(8);110setConfigGreenBits(8);111setConfigBlueBits(8);112}113};114115// Each int parameter can have three values: don't clear, clear, or masked clear. The bool116// parameter controls scissor.117using MaskedScissoredClearVariationsTestParams =118std::tuple<angle::PlatformParameters, int, int, int, bool>;119120void ParseMaskedScissoredClearVariationsTestParams(121const MaskedScissoredClearVariationsTestParams ¶ms,122bool *clearColor,123bool *clearDepth,124bool *clearStencil,125bool *maskColor,126bool *maskDepth,127bool *maskStencil,128bool *scissor)129{130int colorClearInfo = std::get<1>(params);131int depthClearInfo = std::get<2>(params);132int stencilClearInfo = std::get<3>(params);133134*clearColor = colorClearInfo > 0;135*clearDepth = depthClearInfo > 0;136*clearStencil = stencilClearInfo > 0;137138*maskColor = colorClearInfo > 1;139*maskDepth = depthClearInfo > 1;140*maskStencil = stencilClearInfo > 1;141142*scissor = std::get<4>(params);143}144145std::string MaskedScissoredClearVariationsTestPrint(146const ::testing::TestParamInfo<MaskedScissoredClearVariationsTestParams> ¶msInfo)147{148const MaskedScissoredClearVariationsTestParams ¶ms = paramsInfo.param;149std::ostringstream out;150151out << std::get<0>(params);152153bool clearColor, clearDepth, clearStencil;154bool maskColor, maskDepth, maskStencil;155bool scissor;156157ParseMaskedScissoredClearVariationsTestParams(params, &clearColor, &clearDepth, &clearStencil,158&maskColor, &maskDepth, &maskStencil, &scissor);159160if (scissor || clearColor || clearDepth || clearStencil || maskColor || maskDepth ||161maskStencil)162{163out << "_";164}165166if (scissor)167{168out << "_scissored";169}170171if (clearColor || clearDepth || clearStencil)172{173out << "_clear_";174if (clearColor)175{176out << "c";177}178if (clearDepth)179{180out << "d";181}182if (clearStencil)183{184out << "s";185}186}187188if (maskColor || maskDepth || maskStencil)189{190out << "_mask_";191if (maskColor)192{193out << "c";194}195if (maskDepth)196{197out << "d";198}199if (maskStencil)200{201out << "s";202}203}204205return out.str();206}207208class MaskedScissoredClearTestBase209: public ANGLETestWithParam<MaskedScissoredClearVariationsTestParams>210{211protected:212MaskedScissoredClearTestBase()213{214setWindowWidth(128);215setWindowHeight(128);216setConfigRedBits(8);217setConfigGreenBits(8);218setConfigBlueBits(8);219setConfigAlphaBits(8);220setConfigDepthBits(24);221setConfigStencilBits(8);222}223224void maskedScissoredColorDepthStencilClear(225const MaskedScissoredClearVariationsTestParams ¶ms);226227bool mHasDepth = true;228bool mHasStencil = true;229};230231class MaskedScissoredClearTest : public MaskedScissoredClearTestBase232{};233234class VulkanClearTest : public MaskedScissoredClearTestBase235{236protected:237void testSetUp() override238{239glBindTexture(GL_TEXTURE_2D, mColorTexture);240glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,241GL_UNSIGNED_BYTE, nullptr);242243// Setup Color/Stencil FBO with a stencil format that's emulated with packed depth/stencil.244glBindFramebuffer(GL_FRAMEBUFFER, mColorStencilFBO);245246glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mColorTexture,2470);248glBindRenderbuffer(GL_RENDERBUFFER, mStencilTexture);249glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, getWindowWidth(),250getWindowHeight());251glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,252mStencilTexture);253254ASSERT_GL_NO_ERROR();255256// Note: GL_DEPTH_COMPONENT24 is not allowed in GLES2.257if (getClientMajorVersion() >= 3)258{259// Setup Color/Depth FBO with a depth format that's emulated with packed depth/stencil.260glBindFramebuffer(GL_FRAMEBUFFER, mColorDepthFBO);261262glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,263mColorTexture, 0);264glBindRenderbuffer(GL_RENDERBUFFER, mDepthTexture);265glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, getWindowWidth(),266getWindowHeight());267glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,268mDepthTexture);269}270271ASSERT_GL_NO_ERROR();272}273274void bindColorStencilFBO()275{276glBindFramebuffer(GL_FRAMEBUFFER, mColorStencilFBO);277mHasDepth = false;278}279280void bindColorDepthFBO()281{282glBindFramebuffer(GL_FRAMEBUFFER, mColorDepthFBO);283mHasStencil = false;284}285286// Override a feature to force emulation of stencil-only and depth-only formats with a packed287// depth/stencil format288void overrideFeaturesVk(FeaturesVk *featuresVk) override289{290featuresVk->overrideFeatures({"force_fallback_format"}, true);291}292293private:294GLFramebuffer mColorStencilFBO;295GLFramebuffer mColorDepthFBO;296GLTexture mColorTexture;297GLRenderbuffer mDepthTexture;298GLRenderbuffer mStencilTexture;299};300301// Test clearing the default framebuffer302TEST_P(ClearTest, DefaultFramebuffer)303{304glClearColor(0.25f, 0.5f, 0.5f, 0.5f);305glClear(GL_COLOR_BUFFER_BIT);306EXPECT_PIXEL_NEAR(0, 0, 64, 128, 128, 128, 1.0);307}308309// Test clearing the default framebuffer with scissor and mask310// This forces down path that uses draw to do clear311TEST_P(ClearTest, EmptyScissor)312{313// These configs have bug that fails this test.314// These configs are unmaintained so skipping.315ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());316ANGLE_SKIP_TEST_IF(IsOSX());317glClearColor(0.25f, 0.5f, 0.5f, 1.0f);318glClear(GL_COLOR_BUFFER_BIT);319glEnable(GL_SCISSOR_TEST);320glScissor(-10, 0, 5, 5);321glClearColor(0.5f, 0.25f, 0.75f, 0.5f);322glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);323glClear(GL_COLOR_BUFFER_BIT);324glDisable(GL_SCISSOR_TEST);325glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);326EXPECT_PIXEL_NEAR(0, 0, 64, 128, 128, 255, 1.0);327}328329// Test clearing the RGB default framebuffer and verify that the alpha channel is not cleared330TEST_P(ClearTestRGB, DefaultFramebufferRGB)331{332// Some GPUs don't support RGB format default framebuffer,333// so skip if the back buffer has alpha bits.334EGLWindow *window = getEGLWindow();335EGLDisplay display = window->getDisplay();336EGLConfig config = window->getConfig();337EGLint backbufferAlphaBits = 0;338eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &backbufferAlphaBits);339ANGLE_SKIP_TEST_IF(backbufferAlphaBits != 0);340341glClearColor(0.25f, 0.5f, 0.5f, 0.5f);342glClear(GL_COLOR_BUFFER_BIT);343EXPECT_PIXEL_NEAR(0, 0, 64, 128, 128, 255, 1.0);344}345346// Invalidate the RGB default framebuffer and verify that the alpha channel is not cleared, and347// stays set after drawing.348TEST_P(ClearTestRGB, InvalidateDefaultFramebufferRGB)349{350ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());351352// Some GPUs don't support RGB format default framebuffer,353// so skip if the back buffer has alpha bits.354EGLWindow *window = getEGLWindow();355EGLDisplay display = window->getDisplay();356EGLConfig config = window->getConfig();357EGLint backbufferAlphaBits = 0;358eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &backbufferAlphaBits);359ANGLE_SKIP_TEST_IF(backbufferAlphaBits != 0);360// glInvalidateFramebuffer() isn't supported with GLES 2.0361ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);362ANGLE_SKIP_TEST_IF(IsD3D11());363364const GLenum discards[] = {GL_COLOR};365glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);366EXPECT_PIXEL_NEAR(0, 0, 0, 0, 0, 255, 1.0);367368// Don't explicitly clear, but draw blue (make sure alpha is not cleared)369drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);370EXPECT_PIXEL_NEAR(0, 0, 0, 0, 255, 255, 1.0);371}372373// Test clearing a RGBA8 Framebuffer374TEST_P(ClearTest, RGBA8Framebuffer)375{376glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);377378GLTexture texture;379380glBindTexture(GL_TEXTURE_2D, texture);381glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,382GL_UNSIGNED_BYTE, nullptr);383glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);384385glClearColor(0.5f, 0.5f, 0.5f, 0.5f);386glClear(GL_COLOR_BUFFER_BIT);387388EXPECT_PIXEL_NEAR(0, 0, 128, 128, 128, 128, 1.0);389}390391// Test to validate that we can go from an RGBA framebuffer attachment, to an RGB one and still392// have a correct behavior after.393TEST_P(ClearTest, ChangeFramebufferAttachmentFromRGBAtoRGB)394{395// http://anglebug.com/2689396ANGLE_SKIP_TEST_IF(IsD3D9() || IsD3D11() || (IsOzone() && IsOpenGLES()));397ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());398399// http://anglebug.com/5165400ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());401402ANGLE_GL_PROGRAM(program, angle::essl1_shaders::vs::Simple(),403angle::essl1_shaders::fs::UniformColor());404setupQuadVertexBuffer(0.5f, 1.0f);405glUseProgram(program);406GLint positionLocation = glGetAttribLocation(program, angle::essl1_shaders::PositionAttrib());407ASSERT_NE(positionLocation, -1);408glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);409glEnableVertexAttribArray(positionLocation);410411GLint colorUniformLocation =412glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());413ASSERT_NE(colorUniformLocation, -1);414415glUniform4f(colorUniformLocation, 1.0f, 1.0f, 1.0f, 0.5f);416417glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);418419GLTexture texture;420glBindTexture(GL_TEXTURE_2D, texture);421glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,422GL_UNSIGNED_BYTE, nullptr);423glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);424425// Initially clear to black.426glClearColor(0.0f, 0.0f, 0.0f, 1.0f);427glClear(GL_COLOR_BUFFER_BIT);428429// Clear with masked color.430glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);431glClearColor(0.5f, 0.5f, 0.5f, 0.75f);432glClear(GL_COLOR_BUFFER_BIT);433ASSERT_GL_NO_ERROR();434435// So far so good, we have an RGBA framebuffer that we've cleared to 0.5 everywhere.436EXPECT_PIXEL_NEAR(0, 0, 128, 0, 128, 192, 1.0);437438// In the Vulkan backend, RGB textures are emulated with an RGBA texture format439// underneath and we keep a special mask to know that we shouldn't touch the alpha440// channel when we have that emulated texture. This test exists to validate that441// this mask gets updated correctly when the framebuffer attachment changes.442glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB,443GL_UNSIGNED_BYTE, nullptr);444glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);445ASSERT_GL_NO_ERROR();446447glDrawArrays(GL_TRIANGLES, 0, 6);448ASSERT_GL_NO_ERROR();449450EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::magenta);451}452453// Test clearing a RGB8 Framebuffer with a color mask.454TEST_P(ClearTest, RGB8WithMaskFramebuffer)455{456glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);457458GLTexture texture;459460glBindTexture(GL_TEXTURE_2D, texture);461glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB,462GL_UNSIGNED_BYTE, nullptr);463glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);464465glClearColor(0.2f, 0.4f, 0.6f, 0.8f);466glClear(GL_COLOR_BUFFER_BIT);467468// Since there's no alpha, we expect to get 255 back instead of the clear value (204).469EXPECT_PIXEL_NEAR(0, 0, 51, 102, 153, 255, 1.0);470471glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);472glClearColor(0.1f, 0.3f, 0.5f, 0.7f);473glClear(GL_COLOR_BUFFER_BIT);474475// The blue channel was masked so its value should be unchanged.476EXPECT_PIXEL_NEAR(0, 0, 26, 77, 153, 255, 1.0);477478// Restore default.479glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);480}481482TEST_P(ClearTest, ClearIssue)483{484glEnable(GL_DEPTH_TEST);485glDepthFunc(GL_LEQUAL);486487glClearColor(0.0, 1.0, 0.0, 1.0);488glClearDepthf(0.0);489glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);490491EXPECT_GL_NO_ERROR();492493glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);494495GLRenderbuffer rbo;496glBindRenderbuffer(GL_RENDERBUFFER, rbo);497glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB565, 16, 16);498499EXPECT_GL_NO_ERROR();500501glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);502503EXPECT_GL_NO_ERROR();504505glClearColor(1.0f, 0.0f, 0.0f, 1.0f);506glClearDepthf(1.0f);507glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);508509EXPECT_GL_NO_ERROR();510511glBindFramebuffer(GL_FRAMEBUFFER, 0);512glBindBuffer(GL_ARRAY_BUFFER, 0);513514ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());515drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);516517EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);518}519520// Regression test for a bug where "glClearDepthf"'s argument was not clamped521// In GLES 2 they where declared as GLclampf and the behaviour is the same in GLES 3.2522TEST_P(ClearTest, ClearIsClamped)523{524glClearDepthf(5.0f);525526GLfloat clear_depth;527glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clear_depth);528EXPECT_EQ(1.0f, clear_depth);529}530531// Regression test for a bug where "glDepthRangef"'s arguments were not clamped532// In GLES 2 they where declared as GLclampf and the behaviour is the same in GLES 3.2533TEST_P(ClearTest, DepthRangefIsClamped)534{535glDepthRangef(1.1f, -4.0f);536537GLfloat depth_range[2];538glGetFloatv(GL_DEPTH_RANGE, depth_range);539EXPECT_EQ(1.0f, depth_range[0]);540EXPECT_EQ(0.0f, depth_range[1]);541}542543// Test scissored clears on Depth16544TEST_P(ClearTest, Depth16Scissored)545{546GLRenderbuffer renderbuffer;547glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);548constexpr int kRenderbufferSize = 64;549glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, kRenderbufferSize,550kRenderbufferSize);551552GLFramebuffer fbo;553glBindFramebuffer(GL_FRAMEBUFFER, fbo);554glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);555556glClearDepthf(0.0f);557glClear(GL_DEPTH_BUFFER_BIT);558559glEnable(GL_SCISSOR_TEST);560constexpr int kNumSteps = 13;561for (int ndx = 1; ndx < kNumSteps; ndx++)562{563float perc = static_cast<float>(ndx) / static_cast<float>(kNumSteps);564glScissor(0, 0, static_cast<int>(kRenderbufferSize * perc),565static_cast<int>(kRenderbufferSize * perc));566glClearDepthf(perc);567glClear(GL_DEPTH_BUFFER_BIT);568}569}570571// Test scissored clears on Stencil8572TEST_P(ClearTest, Stencil8Scissored)573{574GLRenderbuffer renderbuffer;575glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);576constexpr int kRenderbufferSize = 64;577glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kRenderbufferSize, kRenderbufferSize);578579GLFramebuffer fbo;580glBindFramebuffer(GL_FRAMEBUFFER, fbo);581glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);582583glClearStencil(0);584glClear(GL_STENCIL_BUFFER_BIT);585586glEnable(GL_SCISSOR_TEST);587constexpr int kNumSteps = 13;588for (int ndx = 1; ndx < kNumSteps; ndx++)589{590float perc = static_cast<float>(ndx) / static_cast<float>(kNumSteps);591glScissor(0, 0, static_cast<int>(kRenderbufferSize * perc),592static_cast<int>(kRenderbufferSize * perc));593glClearStencil(static_cast<int>(perc * 255.0f));594glClear(GL_STENCIL_BUFFER_BIT);595}596}597598// Covers a bug in the Vulkan back-end where starting a new command buffer in599// the masked clear would not trigger descriptor sets to be re-bound.600TEST_P(ClearTest, MaskedClearThenDrawWithUniform)601{602// Initialize a program with a uniform.603ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());604glUseProgram(program);605606GLint uniLoc = glGetUniformLocation(program, essl1_shaders::ColorUniform());607ASSERT_NE(-1, uniLoc);608glUniform4f(uniLoc, 0.0f, 1.0f, 0.0f, 1.0f);609610// Initialize position attribute.611GLint posLoc = glGetAttribLocation(program, essl1_shaders::PositionAttrib());612ASSERT_NE(-1, posLoc);613setupQuadVertexBuffer(0.5f, 1.0f);614glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);615glEnableVertexAttribArray(posLoc);616617// Initialize a simple FBO.618constexpr GLsizei kSize = 2;619GLTexture clearTexture;620glBindTexture(GL_TEXTURE_2D, clearTexture);621glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);622623GLFramebuffer fbo;624glBindFramebuffer(GL_FRAMEBUFFER, fbo);625glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, clearTexture, 0);626627glViewport(0, 0, kSize, kSize);628629// Clear and draw to flush out dirty bits.630glClearColor(0.0f, 0.0f, 0.0f, 1.0f);631glClear(GL_COLOR_BUFFER_BIT);632633glDrawArrays(GL_TRIANGLES, 0, 6);634635// Flush to trigger a new serial.636glFlush();637638// Enable color mask and draw again to trigger the bug.639glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);640glClearColor(1.0f, 0.0f, 0.0f, 0.0f);641glClear(GL_COLOR_BUFFER_BIT);642643glDrawArrays(GL_TRIANGLES, 0, 6);644645ASSERT_GL_NO_ERROR();646EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);647}648649// Clear with a mask to verify that masked clear is done properly650// (can't use inline or RenderOp clear when some color channels are masked)651TEST_P(ClearTestES3, ClearPlusMaskDrawAndClear)652{653// Initialize a program with a uniform.654ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());655glUseProgram(program);656657GLint uniLoc = glGetUniformLocation(program, essl1_shaders::ColorUniform());658ASSERT_NE(-1, uniLoc);659glUniform4f(uniLoc, 0.0f, 1.0f, 0.0f, 1.0f);660661// Initialize position attribute.662GLint posLoc = glGetAttribLocation(program, essl1_shaders::PositionAttrib());663ASSERT_NE(-1, posLoc);664setupQuadVertexBuffer(0.5f, 1.0f);665glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);666glEnableVertexAttribArray(posLoc);667668// Initialize a simple FBO.669constexpr GLsizei kSize = 2;670GLTexture clearTexture;671glBindTexture(GL_TEXTURE_2D, clearTexture);672glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);673674GLFramebuffer fbo;675glBindFramebuffer(GL_FRAMEBUFFER, fbo);676glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, clearTexture, 0);677678GLRenderbuffer depthStencil;679glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);680glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);681glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,682depthStencil);683ASSERT_GL_NO_ERROR();684685glViewport(0, 0, kSize, kSize);686687// Clear and draw to flush out dirty bits.688glClearColor(0.0f, 0.0f, 0.0f, 1.0f);689glClearDepthf(1.0f);690glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);691692// Draw green rectangle693glDrawArrays(GL_TRIANGLES, 0, 6);694695// Enable color mask and draw again to trigger the bug.696glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);697glClearColor(0.5f, 0.5f, 0.5f, 1.0f);698glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);699700// Draw purple-ish rectangle, green should be masked off701glUniform4f(uniLoc, 1.0f, 0.25f, 1.0f, 1.0f);702glDrawArrays(GL_TRIANGLES, 0, 6);703704ASSERT_GL_NO_ERROR();705EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);706}707708// Test that clearing all buffers through glClearColor followed by a clear of a specific buffer709// clears to the correct values.710TEST_P(ClearTestES3, ClearMultipleAttachmentsFollowedBySpecificOne)711{712// http://anglebug.com/4092713ANGLE_SKIP_TEST_IF(isSwiftshader());714constexpr uint32_t kSize = 16;715constexpr uint32_t kAttachmentCount = 4;716std::vector<unsigned char> pixelData(kSize * kSize * 4, 255);717718glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);719720GLTexture textures[kAttachmentCount];721GLenum drawBuffers[kAttachmentCount];722GLColor clearValues[kAttachmentCount];723724for (uint32_t i = 0; i < kAttachmentCount; ++i)725{726glBindTexture(GL_TEXTURE_2D, textures[i]);727glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,728pixelData.data());729glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],7300);731drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;732733clearValues[i].R = static_cast<GLubyte>(1 + i * 20);734clearValues[i].G = static_cast<GLubyte>(7 + i * 20);735clearValues[i].B = static_cast<GLubyte>(12 + i * 20);736clearValues[i].A = static_cast<GLubyte>(16 + i * 20);737}738739glDrawBuffers(kAttachmentCount, drawBuffers);740741ASSERT_GL_NO_ERROR();742EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);743744// Clear all targets.745angle::Vector4 clearColor = clearValues[0].toNormalizedVector();746glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);747glClear(GL_COLOR_BUFFER_BIT);748ASSERT_GL_NO_ERROR();749750// Clear odd targets individually.751for (uint32_t i = 1; i < kAttachmentCount; i += 2)752{753clearColor = clearValues[i].toNormalizedVector();754glClearBufferfv(GL_COLOR, i, clearColor.data());755}756757// Even attachments should be cleared to color 0, while odd attachments are cleared to their758// respective color.759for (uint32_t i = 0; i < kAttachmentCount; ++i)760{761glReadBuffer(GL_COLOR_ATTACHMENT0 + i);762ASSERT_GL_NO_ERROR();763764uint32_t clearIndex = i % 2 == 0 ? 0 : i;765const GLColor &expect = clearValues[clearIndex];766767EXPECT_PIXEL_COLOR_EQ(0, 0, expect);768EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, expect);769EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, expect);770EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, expect);771}772}773774// Test that clearing each render target individually works. In the Vulkan backend, this should be775// done in a single render pass.776TEST_P(ClearTestES3, ClearMultipleAttachmentsIndividually)777{778// http://anglebug.com/4855779ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());780781constexpr uint32_t kSize = 16;782constexpr uint32_t kAttachmentCount = 2;783constexpr float kDepthClearValue = 0.125f;784constexpr int32_t kStencilClearValue = 0x67;785std::vector<unsigned char> pixelData(kSize * kSize * 4, 255);786787glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);788789GLTexture textures[kAttachmentCount];790GLRenderbuffer depthStencil;791GLenum drawBuffers[kAttachmentCount];792GLColor clearValues[kAttachmentCount];793794for (uint32_t i = 0; i < kAttachmentCount; ++i)795{796glBindTexture(GL_TEXTURE_2D, textures[i]);797glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,798pixelData.data());799glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],8000);801drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;802803clearValues[i].R = static_cast<GLubyte>(1 + i * 20);804clearValues[i].G = static_cast<GLubyte>(7 + i * 20);805clearValues[i].B = static_cast<GLubyte>(12 + i * 20);806clearValues[i].A = static_cast<GLubyte>(16 + i * 20);807}808809glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);810glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);811glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,812depthStencil);813814glDrawBuffers(kAttachmentCount, drawBuffers);815816ASSERT_GL_NO_ERROR();817EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);818819for (uint32_t i = 0; i < kAttachmentCount; ++i)820{821glClearBufferfv(GL_COLOR, i, clearValues[i].toNormalizedVector().data());822}823824glClearBufferfv(GL_DEPTH, 0, &kDepthClearValue);825glClearBufferiv(GL_STENCIL, 0, &kStencilClearValue);826ASSERT_GL_NO_ERROR();827828for (uint32_t i = 0; i < kAttachmentCount; ++i)829{830glReadBuffer(GL_COLOR_ATTACHMENT0 + i);831ASSERT_GL_NO_ERROR();832833const GLColor &expect = clearValues[i];834835EXPECT_PIXEL_COLOR_EQ(0, 0, expect);836EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, expect);837EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, expect);838EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, expect);839}840841glReadBuffer(GL_COLOR_ATTACHMENT0);842for (uint32_t i = 1; i < kAttachmentCount; ++i)843drawBuffers[i] = GL_NONE;844glDrawBuffers(kAttachmentCount, drawBuffers);845846verifyDepth(kDepthClearValue, kSize);847verifyStencil(kStencilClearValue, kSize);848}849850// Test that clearing multiple attachments in the presence of a color mask, scissor or both851// correctly clears all the attachments.852TEST_P(ClearTestES3, MaskedScissoredClearMultipleAttachments)853{854constexpr uint32_t kSize = 16;855constexpr uint32_t kAttachmentCount = 2;856std::vector<unsigned char> pixelData(kSize * kSize * 4, 255);857858glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);859860GLTexture textures[kAttachmentCount];861GLenum drawBuffers[kAttachmentCount];862863for (uint32_t i = 0; i < kAttachmentCount; ++i)864{865glBindTexture(GL_TEXTURE_2D, textures[i]);866glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,867pixelData.data());868glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],8690);870drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;871}872873glDrawBuffers(kAttachmentCount, drawBuffers);874875ASSERT_GL_NO_ERROR();876EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);877878// Masked clear879GLColor clearColorMasked(31, 63, 255, 191);880angle::Vector4 clearColor = GLColor(31, 63, 127, 191).toNormalizedVector();881882glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);883glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);884glClear(GL_COLOR_BUFFER_BIT);885ASSERT_GL_NO_ERROR();886887// All attachments should be cleared, with the blue channel untouched888for (uint32_t i = 0; i < kAttachmentCount; ++i)889{890glReadBuffer(GL_COLOR_ATTACHMENT0 + i);891ASSERT_GL_NO_ERROR();892893EXPECT_PIXEL_COLOR_EQ(0, 0, clearColorMasked);894EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, clearColorMasked);895EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, clearColorMasked);896EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, clearColorMasked);897EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, clearColorMasked);898}899900// Masked scissored clear901GLColor clearColorMaskedScissored(63, 127, 255, 31);902clearColor = GLColor(63, 127, 191, 31).toNormalizedVector();903904glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);905glEnable(GL_SCISSOR_TEST);906glScissor(kSize / 6, kSize / 6, kSize / 3, kSize / 3);907glClear(GL_COLOR_BUFFER_BIT);908ASSERT_GL_NO_ERROR();909910// The corners should keep the previous value while the center is cleared, except its blue911// channel.912for (uint32_t i = 0; i < kAttachmentCount; ++i)913{914glReadBuffer(GL_COLOR_ATTACHMENT0 + i);915ASSERT_GL_NO_ERROR();916917EXPECT_PIXEL_COLOR_EQ(0, 0, clearColorMasked);918EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, clearColorMasked);919EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, clearColorMasked);920EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, clearColorMasked);921EXPECT_PIXEL_COLOR_EQ(kSize / 3, 2 * kSize / 3, clearColorMasked);922EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3, kSize / 3, clearColorMasked);923EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3, 2 * kSize / 3, clearColorMasked);924925EXPECT_PIXEL_COLOR_EQ(kSize / 3, kSize / 3, clearColorMaskedScissored);926}927928// Scissored clear929GLColor clearColorScissored(127, 191, 31, 63);930clearColor = GLColor(127, 191, 31, 63).toNormalizedVector();931932glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);933glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);934glClear(GL_COLOR_BUFFER_BIT);935ASSERT_GL_NO_ERROR();936937// The corners should keep the old value while all channels of the center are cleared.938for (uint32_t i = 0; i < kAttachmentCount; ++i)939{940glReadBuffer(GL_COLOR_ATTACHMENT0 + i);941ASSERT_GL_NO_ERROR();942943EXPECT_PIXEL_COLOR_EQ(0, 0, clearColorMasked);944EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, clearColorMasked);945EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, clearColorMasked);946EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, clearColorMasked);947EXPECT_PIXEL_COLOR_EQ(kSize / 3, 2 * kSize / 3, clearColorMasked);948EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3, kSize / 3, clearColorMasked);949EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3, 2 * kSize / 3, clearColorMasked);950951EXPECT_PIXEL_COLOR_EQ(kSize / 3, kSize / 3, clearColorScissored);952}953}954955// Test clearing multiple attachments in the presence of an indexed color mask.956TEST_P(ClearTestES3, MaskedIndexedClearMultipleAttachments)957{958ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"));959960constexpr uint32_t kSize = 16;961constexpr uint32_t kAttachmentCount = 4;962std::vector<unsigned char> pixelData(kSize * kSize * 4, 255);963964glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);965966GLTexture textures[kAttachmentCount];967GLenum drawBuffers[kAttachmentCount];968969for (uint32_t i = 0; i < kAttachmentCount; ++i)970{971glBindTexture(GL_TEXTURE_2D, textures[i]);972glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,973pixelData.data());974glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],9750);976drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;977}978979glDrawBuffers(kAttachmentCount, drawBuffers);980981ASSERT_GL_NO_ERROR();982EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);983984// Masked clear985GLColor clearColorMasked(31, 63, 255, 191);986angle::Vector4 clearColor = GLColor(31, 63, 127, 191).toNormalizedVector();987988// Block blue channel for all attachements989glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);990991// Unblock blue channel for attachments 0 and 1992glColorMaskiOES(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);993glColorMaskiOES(1, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);994995glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);996glClear(GL_COLOR_BUFFER_BIT);997ASSERT_GL_NO_ERROR();998999// All attachments should be cleared, with the blue channel untouched for all attachments but 1.1000for (uint32_t i = 0; i < kAttachmentCount; ++i)1001{1002glReadBuffer(GL_COLOR_ATTACHMENT0 + i);1003ASSERT_GL_NO_ERROR();10041005const GLColor attachmentColor = (i > 1) ? clearColorMasked : clearColor;1006EXPECT_PIXEL_COLOR_EQ(0, 0, attachmentColor);1007EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, attachmentColor);1008EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, attachmentColor);1009EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, attachmentColor);1010EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, attachmentColor);1011}1012}10131014// Test that clearing multiple attachments of different nature (float, int and uint) in the1015// presence of a color mask works correctly. In the Vulkan backend, this exercises clearWithDraw1016// and the relevant internal shaders.1017TEST_P(ClearTestES3, MaskedClearHeterogeneousAttachments)1018{1019// http://anglebug.com/48551020ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());10211022// TODO(anglebug.com/5491)1023ANGLE_SKIP_TEST_IF(IsIOS() && IsOpenGLES());10241025constexpr uint32_t kSize = 16;1026constexpr uint32_t kAttachmentCount = 3;1027constexpr float kDepthClearValue = 0.256f;1028constexpr int32_t kStencilClearValue = 0x1D;1029constexpr GLenum kAttachmentFormats[kAttachmentCount] = {1030GL_RGBA8,1031GL_RGBA8I,1032GL_RGBA8UI,1033};1034constexpr GLenum kDataFormats[kAttachmentCount] = {1035GL_RGBA,1036GL_RGBA_INTEGER,1037GL_RGBA_INTEGER,1038};1039constexpr GLenum kDataTypes[kAttachmentCount] = {1040GL_UNSIGNED_BYTE,1041GL_BYTE,1042GL_UNSIGNED_BYTE,1043};10441045std::vector<unsigned char> pixelData(kSize * kSize * 4, 0);10461047glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);10481049GLTexture textures[kAttachmentCount];1050GLRenderbuffer depthStencil;1051GLenum drawBuffers[kAttachmentCount];10521053for (uint32_t i = 0; i < kAttachmentCount; ++i)1054{1055glBindTexture(GL_TEXTURE_2D, textures[i]);1056glTexImage2D(GL_TEXTURE_2D, 0, kAttachmentFormats[i], kSize, kSize, 0, kDataFormats[i],1057kDataTypes[i], pixelData.data());1058glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],10590);1060drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;1061}10621063glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);1064glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);1065glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,1066depthStencil);10671068glDrawBuffers(kAttachmentCount, drawBuffers);10691070ASSERT_GL_NO_ERROR();1071EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0);10721073// Mask out red for all clears1074glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);10751076glClearBufferfv(GL_DEPTH, 0, &kDepthClearValue);1077glClearBufferiv(GL_STENCIL, 0, &kStencilClearValue);10781079GLColor clearValuef = {25, 50, 75, 100};1080glClearBufferfv(GL_COLOR, 0, clearValuef.toNormalizedVector().data());10811082int clearValuei[4] = {10, -20, 30, -40};1083glClearBufferiv(GL_COLOR, 1, clearValuei);10841085uint32_t clearValueui[4] = {50, 60, 70, 80};1086glClearBufferuiv(GL_COLOR, 2, clearValueui);10871088ASSERT_GL_NO_ERROR();10891090{1091glReadBuffer(GL_COLOR_ATTACHMENT0);1092ASSERT_GL_NO_ERROR();10931094GLColor expect = clearValuef;1095expect.R = 0;10961097EXPECT_PIXEL_COLOR_EQ(0, 0, expect);1098EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, expect);1099EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, expect);1100EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, expect);1101}11021103{1104glReadBuffer(GL_COLOR_ATTACHMENT1);1105ASSERT_GL_NO_ERROR();11061107EXPECT_PIXEL_8I(0, 0, 0, clearValuei[1], clearValuei[2], clearValuei[3]);1108EXPECT_PIXEL_8I(0, kSize - 1, 0, clearValuei[1], clearValuei[2], clearValuei[3]);1109EXPECT_PIXEL_8I(kSize - 1, 0, 0, clearValuei[1], clearValuei[2], clearValuei[3]);1110EXPECT_PIXEL_8I(kSize - 1, kSize - 1, 0, clearValuei[1], clearValuei[2], clearValuei[3]);1111}11121113{1114glReadBuffer(GL_COLOR_ATTACHMENT2);1115ASSERT_GL_NO_ERROR();11161117EXPECT_PIXEL_8UI(0, 0, 0, clearValueui[1], clearValueui[2], clearValueui[3]);1118EXPECT_PIXEL_8UI(0, kSize - 1, 0, clearValueui[1], clearValueui[2], clearValueui[3]);1119EXPECT_PIXEL_8UI(kSize - 1, 0, 0, clearValueui[1], clearValueui[2], clearValueui[3]);1120EXPECT_PIXEL_8UI(kSize - 1, kSize - 1, 0, clearValueui[1], clearValueui[2],1121clearValueui[3]);1122}11231124glReadBuffer(GL_COLOR_ATTACHMENT0);1125for (uint32_t i = 1; i < kAttachmentCount; ++i)1126drawBuffers[i] = GL_NONE;1127glDrawBuffers(kAttachmentCount, drawBuffers);11281129verifyDepth(kDepthClearValue, kSize);1130verifyStencil(kStencilClearValue, kSize);1131}11321133// Test that clearing multiple attachments of different nature (float, int and uint) in the1134// presence of a scissor test works correctly. In the Vulkan backend, this exercises clearWithDraw1135// and the relevant internal shaders.1136TEST_P(ClearTestES3, ScissoredClearHeterogeneousAttachments)1137{1138// http://anglebug.com/48551139ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());11401141// http://anglebug.com/51161142ANGLE_SKIP_TEST_IF(IsWindows() && (IsOpenGL() || IsD3D11()) && IsAMD());11431144// http://anglebug.com/52371145ANGLE_SKIP_TEST_IF(IsWindows7() && IsD3D11() && IsNVIDIA());11461147// TODO(anglebug.com/5491)1148ANGLE_SKIP_TEST_IF(IsIOS() && IsOpenGLES());11491150constexpr uint32_t kSize = 16;1151constexpr uint32_t kHalfSize = kSize / 2;1152constexpr uint32_t kAttachmentCount = 3;1153constexpr float kDepthClearValue = 0.256f;1154constexpr int32_t kStencilClearValue = 0x1D;1155constexpr GLenum kAttachmentFormats[kAttachmentCount] = {1156GL_RGBA8,1157GL_RGBA8I,1158GL_RGBA8UI,1159};1160constexpr GLenum kDataFormats[kAttachmentCount] = {1161GL_RGBA,1162GL_RGBA_INTEGER,1163GL_RGBA_INTEGER,1164};1165constexpr GLenum kDataTypes[kAttachmentCount] = {1166GL_UNSIGNED_BYTE,1167GL_BYTE,1168GL_UNSIGNED_BYTE,1169};11701171std::vector<unsigned char> pixelData(kSize * kSize * 4, 0);11721173glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);11741175GLTexture textures[kAttachmentCount];1176GLRenderbuffer depthStencil;1177GLenum drawBuffers[kAttachmentCount];11781179for (uint32_t i = 0; i < kAttachmentCount; ++i)1180{1181glBindTexture(GL_TEXTURE_2D, textures[i]);1182glTexImage2D(GL_TEXTURE_2D, 0, kAttachmentFormats[i], kSize, kSize, 0, kDataFormats[i],1183kDataTypes[i], pixelData.data());1184glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],11850);1186drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;1187}11881189glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);1190glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);1191glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,1192depthStencil);11931194glDrawBuffers(kAttachmentCount, drawBuffers);11951196ASSERT_GL_NO_ERROR();1197EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0);11981199// Enable scissor test1200glScissor(0, 0, kHalfSize, kHalfSize);1201glEnable(GL_SCISSOR_TEST);12021203GLColor clearValuef = {25, 50, 75, 100};1204angle::Vector4 clearValuefv = clearValuef.toNormalizedVector();12051206glClearColor(clearValuefv.x(), clearValuefv.y(), clearValuefv.z(), clearValuefv.w());1207glClearDepthf(kDepthClearValue);12081209// clear stencil.1210glClearBufferiv(GL_STENCIL, 0, &kStencilClearValue);12111212// clear float color attachment & depth together1213glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);12141215// clear integer attachment.1216int clearValuei[4] = {10, -20, 30, -40};1217glClearBufferiv(GL_COLOR, 1, clearValuei);12181219// clear unsigned integer attachment1220uint32_t clearValueui[4] = {50, 60, 70, 80};1221glClearBufferuiv(GL_COLOR, 2, clearValueui);12221223ASSERT_GL_NO_ERROR();12241225{1226glReadBuffer(GL_COLOR_ATTACHMENT0);1227ASSERT_GL_NO_ERROR();12281229GLColor expect = clearValuef;12301231EXPECT_PIXEL_COLOR_EQ(0, 0, expect);1232EXPECT_PIXEL_COLOR_EQ(0, kHalfSize - 1, expect);1233EXPECT_PIXEL_COLOR_EQ(kHalfSize - 1, 0, expect);1234EXPECT_PIXEL_COLOR_EQ(kHalfSize - 1, kHalfSize - 1, expect);1235EXPECT_PIXEL_EQ(kHalfSize + 1, kHalfSize + 1, 0, 0, 0, 0);1236}12371238{1239glReadBuffer(GL_COLOR_ATTACHMENT1);1240ASSERT_GL_NO_ERROR();12411242EXPECT_PIXEL_8I(0, 0, clearValuei[0], clearValuei[1], clearValuei[2], clearValuei[3]);1243EXPECT_PIXEL_8I(0, kHalfSize - 1, clearValuei[0], clearValuei[1], clearValuei[2],1244clearValuei[3]);1245EXPECT_PIXEL_8I(kHalfSize - 1, 0, clearValuei[0], clearValuei[1], clearValuei[2],1246clearValuei[3]);1247EXPECT_PIXEL_8I(kHalfSize - 1, kHalfSize - 1, clearValuei[0], clearValuei[1],1248clearValuei[2], clearValuei[3]);1249EXPECT_PIXEL_8I(kHalfSize + 1, kHalfSize + 1, 0, 0, 0, 0);1250}12511252{1253glReadBuffer(GL_COLOR_ATTACHMENT2);1254ASSERT_GL_NO_ERROR();12551256EXPECT_PIXEL_8UI(0, 0, clearValueui[0], clearValueui[1], clearValueui[2], clearValueui[3]);1257EXPECT_PIXEL_8UI(0, kHalfSize - 1, clearValueui[0], clearValueui[1], clearValueui[2],1258clearValueui[3]);1259EXPECT_PIXEL_8UI(kHalfSize - 1, 0, clearValueui[0], clearValueui[1], clearValueui[2],1260clearValueui[3]);1261EXPECT_PIXEL_8UI(kHalfSize - 1, kHalfSize - 1, clearValueui[0], clearValueui[1],1262clearValueui[2], clearValueui[3]);1263EXPECT_PIXEL_8UI(kHalfSize + 1, kHalfSize + 1, 0, 0, 0, 0);1264}12651266glReadBuffer(GL_COLOR_ATTACHMENT0);1267for (uint32_t i = 1; i < kAttachmentCount; ++i)1268drawBuffers[i] = GL_NONE;1269glDrawBuffers(kAttachmentCount, drawBuffers);12701271verifyDepth(kDepthClearValue, kHalfSize);1272verifyStencil(kStencilClearValue, kHalfSize);1273}12741275// This tests a bug where in a masked clear when calling "ClearBuffer", we would1276// mistakenly clear every channel (including the masked-out ones)1277TEST_P(ClearTestES3, MaskedClearBufferBug)1278{1279// TODO(syoussefi): Qualcomm driver crashes in the presence of VK_ATTACHMENT_UNUSED.1280// http://anglebug.com/34231281ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());12821283unsigned char pixelData[] = {255, 255, 255, 255};12841285glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);12861287GLTexture textures[2];12881289glBindTexture(GL_TEXTURE_2D, textures[0]);1290glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);1291glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);12921293glBindTexture(GL_TEXTURE_2D, textures[1]);1294glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);1295glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, textures[1], 0);12961297ASSERT_GL_NO_ERROR();1298EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255);12991300float clearValue[] = {0, 0.5f, 0.5f, 1.0f};1301GLenum drawBuffers[] = {GL_NONE, GL_COLOR_ATTACHMENT1};1302glDrawBuffers(2, drawBuffers);1303glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);1304glClearBufferfv(GL_COLOR, 1, clearValue);13051306ASSERT_GL_NO_ERROR();1307EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255);13081309glReadBuffer(GL_COLOR_ATTACHMENT1);1310ASSERT_GL_NO_ERROR();13111312EXPECT_PIXEL_NEAR(0, 0, 0, 127, 255, 255, 1);1313}13141315TEST_P(ClearTestES3, BadFBOSerialBug)1316{1317// First make a simple framebuffer, and clear it to green1318glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);13191320GLTexture textures[2];13211322glBindTexture(GL_TEXTURE_2D, textures[0]);1323glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());1324glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);13251326GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0};1327glDrawBuffers(1, drawBuffers);13281329float clearValues1[] = {0.0f, 1.0f, 0.0f, 1.0f};1330glClearBufferfv(GL_COLOR, 0, clearValues1);13311332ASSERT_GL_NO_ERROR();1333EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);13341335// Next make a second framebuffer, and draw it to red1336// (Triggers bad applied render target serial)1337GLFramebuffer fbo2;1338glBindFramebuffer(GL_FRAMEBUFFER, fbo2);1339ASSERT_GL_NO_ERROR();13401341glBindTexture(GL_TEXTURE_2D, textures[1]);1342glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());1343glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);13441345glDrawBuffers(1, drawBuffers);13461347ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());1348drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);13491350ASSERT_GL_NO_ERROR();1351EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);13521353// Check that the first framebuffer is still green.1354glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);1355EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);1356}13571358// Test that SRGB framebuffers clear to the linearized clear color1359TEST_P(ClearTestES3, SRGBClear)1360{1361// First make a simple framebuffer, and clear it1362glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);13631364GLTexture texture;13651366glBindTexture(GL_TEXTURE_2D, texture);1367glTexStorage2D(GL_TEXTURE_2D, 1, GL_SRGB8_ALPHA8, getWindowWidth(), getWindowHeight());1368glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);13691370glClearColor(0.5f, 0.5f, 0.5f, 0.5f);1371glClear(GL_COLOR_BUFFER_BIT);13721373EXPECT_PIXEL_NEAR(0, 0, 188, 188, 188, 128, 1.0);1374}13751376// Test that framebuffers with mixed SRGB/Linear attachments clear to the correct color for each1377// attachment1378TEST_P(ClearTestES3, MixedSRGBClear)1379{1380glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);13811382GLTexture textures[2];13831384glBindTexture(GL_TEXTURE_2D, textures[0]);1385glTexStorage2D(GL_TEXTURE_2D, 1, GL_SRGB8_ALPHA8, getWindowWidth(), getWindowHeight());1386glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);13871388glBindTexture(GL_TEXTURE_2D, textures[1]);1389glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());1390glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, textures[1], 0);13911392GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};1393glDrawBuffers(2, drawBuffers);13941395// Clear both textures1396glClearColor(0.5f, 0.5f, 0.5f, 0.5f);1397glClear(GL_COLOR_BUFFER_BIT);13981399glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);1400glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, 0, 0);14011402// Check value of texture01403glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);1404EXPECT_PIXEL_NEAR(0, 0, 188, 188, 188, 128, 1.0);14051406// Check value of texture11407glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);1408EXPECT_PIXEL_NEAR(0, 0, 128, 128, 128, 128, 1.0);1409}14101411// This test covers a D3D11 bug where calling ClearRenderTargetView sometimes wouldn't sync1412// before a draw call. The test draws small quads to a larger FBO (the default back buffer).1413// Before each blit to the back buffer it clears the quad to a certain color using1414// ClearBufferfv to give a solid color. The sync problem goes away if we insert a call to1415// flush or finish after ClearBufferfv or each draw.1416TEST_P(ClearTestES3, RepeatedClear)1417{1418// Fails on 431.02 driver. http://anglebug.com/37481419ANGLE_SKIP_TEST_IF(IsWindows() && IsNVIDIA() && IsVulkan());1420ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());14211422constexpr char kVS[] =1423"#version 300 es\n"1424"in highp vec2 position;\n"1425"out highp vec2 v_coord;\n"1426"void main(void)\n"1427"{\n"1428" gl_Position = vec4(position, 0, 1);\n"1429" vec2 texCoord = (position * 0.5) + 0.5;\n"1430" v_coord = texCoord;\n"1431"}\n";14321433constexpr char kFS[] =1434"#version 300 es\n"1435"in highp vec2 v_coord;\n"1436"out highp vec4 color;\n"1437"uniform sampler2D tex;\n"1438"void main()\n"1439"{\n"1440" color = texture(tex, v_coord);\n"1441"}\n";14421443ANGLE_GL_PROGRAM(program, kVS, kFS);14441445mTextures.resize(1, 0);1446glGenTextures(1, mTextures.data());14471448GLenum format = GL_RGBA8;1449const int numRowsCols = 3;1450const int cellSize = 32;1451const int fboSize = cellSize;1452const int backFBOSize = cellSize * numRowsCols;1453const float fmtValueMin = 0.0f;1454const float fmtValueMax = 1.0f;14551456glBindTexture(GL_TEXTURE_2D, mTextures[0]);1457glTexStorage2D(GL_TEXTURE_2D, 1, format, fboSize, fboSize);1458glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);1459glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);1460glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);1461glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);1462ASSERT_GL_NO_ERROR();14631464glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);1465glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);1466ASSERT_GL_NO_ERROR();14671468ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));14691470// larger fbo bound -- clear to transparent black1471glUseProgram(program);1472GLint uniLoc = glGetUniformLocation(program, "tex");1473ASSERT_NE(-1, uniLoc);1474glUniform1i(uniLoc, 0);1475glBindTexture(GL_TEXTURE_2D, mTextures[0]);14761477GLint positionLocation = glGetAttribLocation(program, "position");1478ASSERT_NE(-1, positionLocation);14791480glUseProgram(program);14811482for (int cellY = 0; cellY < numRowsCols; cellY++)1483{1484for (int cellX = 0; cellX < numRowsCols; cellX++)1485{1486int seed = cellX + cellY * numRowsCols;1487const Vector4 color = RandomVec4(seed, fmtValueMin, fmtValueMax);14881489glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);1490glClearBufferfv(GL_COLOR, 0, color.data());14911492glBindFramebuffer(GL_FRAMEBUFFER, 0);14931494// Method 1: Set viewport and draw full-viewport quad1495glViewport(cellX * cellSize, cellY * cellSize, cellSize, cellSize);1496drawQuad(program, "position", 0.5f);14971498// Uncommenting the glFinish call seems to make the test pass.1499// glFinish();1500}1501}15021503std::vector<GLColor> pixelData(backFBOSize * backFBOSize);1504glReadPixels(0, 0, backFBOSize, backFBOSize, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());15051506for (int cellY = 0; cellY < numRowsCols; cellY++)1507{1508for (int cellX = 0; cellX < numRowsCols; cellX++)1509{1510int seed = cellX + cellY * numRowsCols;1511const Vector4 color = RandomVec4(seed, fmtValueMin, fmtValueMax);1512GLColor expectedColor(color);15131514int testN = cellX * cellSize + cellY * backFBOSize * cellSize + backFBOSize + 1;1515GLColor actualColor = pixelData[testN];1516EXPECT_NEAR(expectedColor.R, actualColor.R, 1);1517EXPECT_NEAR(expectedColor.G, actualColor.G, 1);1518EXPECT_NEAR(expectedColor.B, actualColor.B, 1);1519EXPECT_NEAR(expectedColor.A, actualColor.A, 1);1520}1521}15221523ASSERT_GL_NO_ERROR();1524}15251526// Test that clearing RGB8 attachments from a 2D texture array does not cause1527// VUID-VkImageMemoryBarrier-oldLayout-011971528TEST_P(ClearTestES3, TextureArrayRGB8)1529{1530GLFramebuffer fb;1531glBindFramebuffer(GL_FRAMEBUFFER, fb);15321533GLTexture tex;1534glBindTexture(GL_TEXTURE_2D_ARRAY, tex);1535glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGB8, 1, 1, 2);1536glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);1537glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);15381539glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0);1540glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, tex, 0, 1);15411542ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);15431544GLenum bufs[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};1545glDrawBuffers(2, &bufs[0]);15461547glClearColor(1.0, 0.0, 1.0, 1.0);1548glClear(GL_COLOR_BUFFER_BIT);1549ASSERT_GL_NO_ERROR();15501551glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);15521553glReadBuffer(GL_COLOR_ATTACHMENT0);1554EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);15551556glReadBuffer(GL_COLOR_ATTACHMENT1);1557EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);15581559EXPECT_GL_NO_ERROR();1560}15611562void MaskedScissoredClearTestBase::maskedScissoredColorDepthStencilClear(1563const MaskedScissoredClearVariationsTestParams ¶ms)1564{1565// Flaky on Android Nexus 5x and Pixel 2, possible Qualcomm driver bug.1566// TODO(jmadill): Re-enable when possible. http://anglebug.com/25481567ANGLE_SKIP_TEST_IF(IsOpenGLES() && IsAndroid());15681569const int w = getWindowWidth();1570const int h = getWindowHeight();1571const int wthird = w / 3;1572const int hthird = h / 3;15731574constexpr float kPreClearDepth = 0.9f;1575constexpr float kClearDepth = 0.5f;1576constexpr uint8_t kPreClearStencil = 0xFF;1577constexpr uint8_t kClearStencil = 0x16;1578constexpr uint8_t kStencilMask = 0x59;1579constexpr uint8_t kMaskedClearStencil =1580(kPreClearStencil & ~kStencilMask) | (kClearStencil & kStencilMask);15811582bool clearColor, clearDepth, clearStencil;1583bool maskColor, maskDepth, maskStencil;1584bool scissor;15851586ParseMaskedScissoredClearVariationsTestParams(params, &clearColor, &clearDepth, &clearStencil,1587&maskColor, &maskDepth, &maskStencil, &scissor);15881589// clearDepth && !maskDepth fails on Intel Ubuntu 19.04 Mesa 19.0.2 GL. http://anglebug.com/36141590ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsDesktopOpenGL() && clearDepth && !maskDepth);15911592// Clear to a random color, 0.9 depth and 0x00 stencil1593Vector4 color1(0.1f, 0.2f, 0.3f, 0.4f);1594GLColor color1RGB(color1);15951596glClearColor(color1[0], color1[1], color1[2], color1[3]);1597glClearDepthf(kPreClearDepth);1598glClearStencil(kPreClearStencil);15991600if (!clearColor)1601{1602// If not asked to clear color, clear it anyway, but individually. The clear value is1603// still used to verify that the depth/stencil clear happened correctly. This allows1604// testing for depth/stencil-only clear implementations.1605glClear(GL_COLOR_BUFFER_BIT);1606}16071608glClear((clearColor ? GL_COLOR_BUFFER_BIT : 0) | (clearDepth ? GL_DEPTH_BUFFER_BIT : 0) |1609(clearStencil ? GL_STENCIL_BUFFER_BIT : 0));1610ASSERT_GL_NO_ERROR();16111612// Verify color was cleared correctly.1613EXPECT_PIXEL_COLOR_NEAR(0, 0, color1RGB, 1);16141615if (scissor)1616{1617glEnable(GL_SCISSOR_TEST);1618glScissor(wthird / 2, hthird / 2, wthird, hthird);1619}16201621// Use color and stencil masks to clear to a second color, 0.5 depth and 0x59 stencil.1622Vector4 color2(0.2f, 0.4f, 0.6f, 0.8f);1623GLColor color2RGB(color2);1624glClearColor(color2[0], color2[1], color2[2], color2[3]);1625glClearDepthf(kClearDepth);1626glClearStencil(kClearStencil);1627if (maskColor)1628{1629glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_FALSE);1630}1631if (maskDepth)1632{1633glDepthMask(GL_FALSE);1634}1635if (maskStencil)1636{1637glStencilMask(kStencilMask);1638}1639glClear((clearColor ? GL_COLOR_BUFFER_BIT : 0) | (clearDepth ? GL_DEPTH_BUFFER_BIT : 0) |1640(clearStencil ? GL_STENCIL_BUFFER_BIT : 0));1641glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);1642glDepthMask(GL_TRUE);1643glStencilMask(0xFF);1644glDisable(GL_DEPTH_TEST);1645glDisable(GL_STENCIL_TEST);1646glDisable(GL_SCISSOR_TEST);1647ASSERT_GL_NO_ERROR();16481649GLColor color2MaskedRGB(color2RGB[0], color1RGB[1], color2RGB[2], color1RGB[3]);16501651// If not clearing color, the original color should be left both in the center and corners. If1652// using a scissor, the corners should be left to the original color, while the center is1653// possibly changed. If using a mask, the center (and corners if not scissored), changes to1654// the masked results.1655GLColor expectedCenterColorRGB =1656!clearColor ? color1RGB : maskColor ? color2MaskedRGB : color2RGB;1657GLColor expectedCornerColorRGB = scissor ? color1RGB : expectedCenterColorRGB;16581659// Verify second clear color mask worked as expected.1660EXPECT_PIXEL_COLOR_NEAR(wthird, hthird, expectedCenterColorRGB, 1);16611662EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedCornerColorRGB, 1);1663EXPECT_PIXEL_COLOR_NEAR(w - 1, 0, expectedCornerColorRGB, 1);1664EXPECT_PIXEL_COLOR_NEAR(0, h - 1, expectedCornerColorRGB, 1);1665EXPECT_PIXEL_COLOR_NEAR(w - 1, h - 1, expectedCornerColorRGB, 1);1666EXPECT_PIXEL_COLOR_NEAR(wthird, 2 * hthird, expectedCornerColorRGB, 1);1667EXPECT_PIXEL_COLOR_NEAR(2 * wthird, hthird, expectedCornerColorRGB, 1);1668EXPECT_PIXEL_COLOR_NEAR(2 * wthird, 2 * hthird, expectedCornerColorRGB, 1);16691670// If there is depth, but depth is not asked to be cleared, the depth buffer contains garbage,1671// so no particular behavior can be expected.1672if (clearDepth || !mHasDepth)1673{1674// We use a small shader to verify depth.1675ANGLE_GL_PROGRAM(depthTestProgram, essl1_shaders::vs::Passthrough(),1676essl1_shaders::fs::Blue());1677glEnable(GL_DEPTH_TEST);1678glDepthFunc(maskDepth ? GL_GREATER : GL_EQUAL);1679// - If depth is cleared, but it's masked, kPreClearDepth should be in the depth buffer.1680// - If depth is cleared, but it's not masked, kClearDepth should be in the depth buffer.1681// - If depth is not cleared, the if above ensures there is no depth buffer at all,1682// which means depth test will always pass.1683drawQuad(depthTestProgram, essl1_shaders::PositionAttrib(), maskDepth ? 1.0f : 0.0f);1684glDisable(GL_DEPTH_TEST);1685ASSERT_GL_NO_ERROR();16861687// Either way, we expect blue to be written to the center.1688expectedCenterColorRGB = GLColor::blue;1689// If there is no depth, depth test always passes so the whole image must be blue. Same if1690// depth write is masked.1691expectedCornerColorRGB =1692mHasDepth && scissor && !maskDepth ? expectedCornerColorRGB : GLColor::blue;16931694EXPECT_PIXEL_COLOR_NEAR(wthird, hthird, expectedCenterColorRGB, 1);16951696EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedCornerColorRGB, 1);1697EXPECT_PIXEL_COLOR_NEAR(w - 1, 0, expectedCornerColorRGB, 1);1698EXPECT_PIXEL_COLOR_NEAR(0, h - 1, expectedCornerColorRGB, 1);1699EXPECT_PIXEL_COLOR_NEAR(w - 1, h - 1, expectedCornerColorRGB, 1);1700EXPECT_PIXEL_COLOR_NEAR(wthird, 2 * hthird, expectedCornerColorRGB, 1);1701EXPECT_PIXEL_COLOR_NEAR(2 * wthird, hthird, expectedCornerColorRGB, 1);1702EXPECT_PIXEL_COLOR_NEAR(2 * wthird, 2 * hthird, expectedCornerColorRGB, 1);1703}17041705// If there is stencil, but it's not asked to be cleared, there is similarly no expectation.1706if (clearStencil || !mHasStencil)1707{1708// And another small shader to verify stencil.1709ANGLE_GL_PROGRAM(stencilTestProgram, essl1_shaders::vs::Passthrough(),1710essl1_shaders::fs::Green());1711glEnable(GL_STENCIL_TEST);1712// - If stencil is cleared, but it's masked, kMaskedClearStencil should be in the stencil1713// buffer.1714// - If stencil is cleared, but it's not masked, kClearStencil should be in the stencil1715// buffer.1716// - If stencil is not cleared, the if above ensures there is no stencil buffer at all,1717// which means stencil test will always pass.1718glStencilFunc(GL_EQUAL, maskStencil ? kMaskedClearStencil : kClearStencil, 0xFF);1719drawQuad(stencilTestProgram, essl1_shaders::PositionAttrib(), 0.0f);1720glDisable(GL_STENCIL_TEST);1721ASSERT_GL_NO_ERROR();17221723// Either way, we expect green to be written to the center.1724expectedCenterColorRGB = GLColor::green;1725// If there is no stencil, stencil test always passes so the whole image must be green.1726expectedCornerColorRGB = mHasStencil && scissor ? expectedCornerColorRGB : GLColor::green;17271728EXPECT_PIXEL_COLOR_NEAR(wthird, hthird, expectedCenterColorRGB, 1);17291730EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedCornerColorRGB, 1);1731EXPECT_PIXEL_COLOR_NEAR(w - 1, 0, expectedCornerColorRGB, 1);1732EXPECT_PIXEL_COLOR_NEAR(0, h - 1, expectedCornerColorRGB, 1);1733EXPECT_PIXEL_COLOR_NEAR(w - 1, h - 1, expectedCornerColorRGB, 1);1734EXPECT_PIXEL_COLOR_NEAR(wthird, 2 * hthird, expectedCornerColorRGB, 1);1735EXPECT_PIXEL_COLOR_NEAR(2 * wthird, hthird, expectedCornerColorRGB, 1);1736EXPECT_PIXEL_COLOR_NEAR(2 * wthird, 2 * hthird, expectedCornerColorRGB, 1);1737}1738}17391740// Tests combinations of color, depth, stencil clears with or without masks or scissor.1741TEST_P(MaskedScissoredClearTest, Test)1742{1743maskedScissoredColorDepthStencilClear(GetParam());1744}17451746// Tests combinations of color, depth, stencil clears with or without masks or scissor.1747//1748// This uses depth/stencil attachments that are single-channel, but are emulated with a format1749// that has both channels.1750TEST_P(VulkanClearTest, Test)1751{1752bool clearColor, clearDepth, clearStencil;1753bool maskColor, maskDepth, maskStencil;1754bool scissor;17551756ParseMaskedScissoredClearVariationsTestParams(GetParam(), &clearColor, &clearDepth,1757&clearStencil, &maskColor, &maskDepth,1758&maskStencil, &scissor);17591760// We only care about clearing depth xor stencil.1761if (clearDepth == clearStencil)1762{1763return;1764}17651766if (clearDepth)1767{1768// Creating a depth-only renderbuffer is an ES3 feature.1769ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);1770bindColorDepthFBO();1771}1772else1773{1774bindColorStencilFBO();1775}17761777maskedScissoredColorDepthStencilClear(GetParam());1778}17791780// Tests that clearing a non existing attachment works.1781TEST_P(ClearTest, ClearColorThenClearNonExistingDepthStencil)1782{1783constexpr GLsizei kSize = 16;17841785GLTexture color;1786glBindTexture(GL_TEXTURE_2D, color);1787glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);17881789GLFramebuffer fbo;1790glBindFramebuffer(GL_FRAMEBUFFER, fbo);1791glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);1792ASSERT_GL_NO_ERROR();1793ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);17941795// Clear color.1796glClearColor(1.0f, 0.0f, 0.0f, 1.0f);1797glClear(GL_COLOR_BUFFER_BIT);17981799// Clear depth/stencil.1800glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);1801ASSERT_GL_NO_ERROR();18021803// Read back color.1804EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);1805}18061807// Tests that clearing a non existing attachment works.1808TEST_P(ClearTestES3, ClearDepthStencilThenClearNonExistingColor)1809{1810constexpr GLsizei kSize = 16;18111812GLRenderbuffer depth;1813glBindRenderbuffer(GL_RENDERBUFFER, depth);1814glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);18151816GLFramebuffer fbo;1817glBindFramebuffer(GL_FRAMEBUFFER, fbo);1818glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depth);1819ASSERT_GL_NO_ERROR();1820ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);18211822// Clear depth/stencil.1823glClearDepthf(1.0f);1824glClearStencil(0xAA);1825glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);1826ASSERT_GL_NO_ERROR();18271828// Clear color.1829glClearColor(1.0f, 0.0f, 0.0f, 1.0f);1830glClear(GL_COLOR_BUFFER_BIT);1831ASSERT_GL_NO_ERROR();1832}18331834// Test that just clearing a nonexistent drawbuffer of the default framebuffer doesn't cause an1835// assert.1836TEST_P(ClearTestES3, ClearBuffer1OnDefaultFramebufferNoAssert)1837{1838std::vector<GLuint> testUint(4);1839glClearBufferuiv(GL_COLOR, 1, testUint.data());1840std::vector<GLint> testInt(4);1841glClearBufferiv(GL_COLOR, 1, testInt.data());1842std::vector<GLfloat> testFloat(4);1843glClearBufferfv(GL_COLOR, 1, testFloat.data());1844EXPECT_GL_NO_ERROR();1845}18461847// Clears many small concentric rectangles using scissor regions.1848TEST_P(ClearTest, InceptionScissorClears)1849{1850angle::RNG rng;18511852constexpr GLuint kSize = 16;18531854// Create a square user FBO so we have more control over the dimensions.1855GLFramebuffer fbo;1856glBindFramebuffer(GL_FRAMEBUFFER, fbo);18571858GLRenderbuffer rbo;1859glBindRenderbuffer(GL_RENDERBUFFER, rbo);1860glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);18611862glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);1863ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);18641865glViewport(0, 0, kSize, kSize);18661867// Draw small concentric squares using scissor.1868std::vector<GLColor> expectedColors;1869for (GLuint index = 0; index < (kSize - 1) / 2; index++)1870{1871// Do the first clear without the scissor.1872if (index > 0)1873{1874glEnable(GL_SCISSOR_TEST);1875glScissor(index, index, kSize - (index * 2), kSize - (index * 2));1876}18771878GLColor color = RandomColor(&rng);1879expectedColors.push_back(color);1880Vector4 floatColor = color.toNormalizedVector();1881glClearColor(floatColor[0], floatColor[1], floatColor[2], floatColor[3]);1882glClear(GL_COLOR_BUFFER_BIT);1883}18841885ASSERT_GL_NO_ERROR();18861887std::vector<GLColor> actualColors(expectedColors.size());1888glReadPixels(0, kSize / 2, actualColors.size(), 1, GL_RGBA, GL_UNSIGNED_BYTE,1889actualColors.data());18901891EXPECT_EQ(expectedColors, actualColors);1892}18931894// Test that clearBuffer with disabled non-zero drawbuffer or disabled read source doesn't cause an1895// assert.1896TEST_P(ClearTestES3, ClearDisabledNonZeroAttachmentNoAssert)1897{1898// http://anglebug.com/46121899ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());19001901GLFramebuffer fb;1902glBindFramebuffer(GL_FRAMEBUFFER, fb);19031904GLRenderbuffer rb;1905glBindRenderbuffer(GL_RENDERBUFFER, rb);1906glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 16, 16);19071908glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rb);1909glDrawBuffers(0, nullptr);1910glReadBuffer(GL_NONE);19111912ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);19131914float clearColorf[4] = {0.5, 0.5, 0.5, 0.5};1915glClearBufferfv(GL_COLOR, 1, clearColorf);19161917GLuint clearColorui[4] = {255, 255, 255, 255};1918glClearBufferuiv(GL_COLOR, 1, clearColorui);19191920GLint clearColori[4] = {-127, -127, -127, -127};1921glClearBufferiv(GL_COLOR, 1, clearColori);19221923EXPECT_GL_NO_ERROR();1924}19251926// Test that having a framebuffer with maximum number of attachments and clearing color, depth and1927// stencil works.1928TEST_P(ClearTestES3, ClearMaxAttachments)1929{1930// http://anglebug.com/46121931ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());1932// http://anglebug.com/53971933ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D11());19341935constexpr GLsizei kSize = 16;19361937GLint maxDrawBuffers = 0;1938glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);1939ASSERT_GE(maxDrawBuffers, 4);19401941// Setup framebuffer.1942GLFramebuffer fb;1943glBindFramebuffer(GL_FRAMEBUFFER, fb);19441945std::vector<GLRenderbuffer> color(maxDrawBuffers);1946std::vector<GLenum> drawBuffers(maxDrawBuffers);19471948for (GLint colorIndex = 0; colorIndex < maxDrawBuffers; ++colorIndex)1949{1950glBindRenderbuffer(GL_RENDERBUFFER, color[colorIndex]);1951glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);1952glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + colorIndex,1953GL_RENDERBUFFER, color[colorIndex]);19541955drawBuffers[colorIndex] = GL_COLOR_ATTACHMENT0 + colorIndex;1956}19571958GLRenderbuffer depthStencil;1959glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);1960glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);1961glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,1962depthStencil);19631964EXPECT_GL_NO_ERROR();1965ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);19661967glDrawBuffers(maxDrawBuffers, drawBuffers.data());19681969glClearColor(1.0f, 0.0f, 0.0f, 1.0f);1970glClearDepthf(1.0f);1971glClearStencil(0x55);1972glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);1973EXPECT_GL_NO_ERROR();19741975// Verify that every color attachment is cleared correctly.1976for (GLint colorIndex = 0; colorIndex < maxDrawBuffers; ++colorIndex)1977{1978glReadBuffer(GL_COLOR_ATTACHMENT0 + colorIndex);19791980EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);1981EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::red);1982EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red);1983EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red);1984}19851986// Verify that depth and stencil attachments are cleared correctly.1987GLFramebuffer fbVerify;1988glBindFramebuffer(GL_FRAMEBUFFER, fbVerify);19891990glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color[0]);1991glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,1992depthStencil);19931994// If depth is not cleared to 1, rendering would fail.1995glEnable(GL_DEPTH_TEST);1996glDepthFunc(GL_LESS);19971998// If stencil is not cleared to 0x55, rendering would fail.1999glEnable(GL_STENCIL_TEST);2000glStencilFunc(GL_EQUAL, 0x55, 0xFF);2001glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);2002glStencilMask(0xFF);20032004// Draw green.2005ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());2006drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.95f);20072008// Verify that green was drawn.2009EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);2010EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);2011EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);2012EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);2013}20142015// Test that having a framebuffer with maximum number of attachments and clearing color, depth and2016// stencil after a draw call works.2017TEST_P(ClearTestES3, ClearMaxAttachmentsAfterDraw)2018{2019// http://anglebug.com/46122020ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());20212022constexpr GLsizei kSize = 16;20232024GLint maxDrawBuffers = 0;2025glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);2026ASSERT_GE(maxDrawBuffers, 4);20272028// Setup framebuffer.2029GLFramebuffer fb;2030glBindFramebuffer(GL_FRAMEBUFFER, fb);20312032std::vector<GLRenderbuffer> color(maxDrawBuffers);2033std::vector<GLenum> drawBuffers(maxDrawBuffers);20342035for (GLint colorIndex = 0; colorIndex < maxDrawBuffers; ++colorIndex)2036{2037glBindRenderbuffer(GL_RENDERBUFFER, color[colorIndex]);2038glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);2039glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + colorIndex,2040GL_RENDERBUFFER, color[colorIndex]);20412042drawBuffers[colorIndex] = GL_COLOR_ATTACHMENT0 + colorIndex;2043}20442045GLRenderbuffer depthStencil;2046glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);2047glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);2048glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,2049depthStencil);20502051EXPECT_GL_NO_ERROR();2052ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);20532054glDrawBuffers(maxDrawBuffers, drawBuffers.data());20552056// Issue a draw call to render blue, depth=0 and stencil 0x3C to the attachments.2057glEnable(GL_DEPTH_TEST);2058glDepthFunc(GL_ALWAYS);20592060glEnable(GL_STENCIL_TEST);2061glStencilFunc(GL_ALWAYS, 0x3C, 0xFF);2062glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);2063glStencilMask(0xFF);20642065// Generate shader for this framebuffer.2066std::stringstream strstr;2067strstr << "#version 300 es\n"2068"precision highp float;\n";2069for (GLint colorIndex = 0; colorIndex < maxDrawBuffers; ++colorIndex)2070{2071strstr << "layout(location = " << colorIndex << ") out vec4 value" << colorIndex << ";\n";2072}2073strstr << "void main()\n"2074"{\n";2075for (GLint colorIndex = 0; colorIndex < maxDrawBuffers; ++colorIndex)2076{2077strstr << "value" << colorIndex << " = vec4(0.0f, 0.0f, 1.0f, 1.0f);\n";2078}2079strstr << "}\n";20802081ANGLE_GL_PROGRAM(drawMRT, essl3_shaders::vs::Simple(), strstr.str().c_str());2082drawQuad(drawMRT, essl3_shaders::PositionAttrib(), 0.0f);2083ASSERT_GL_NO_ERROR();20842085glClearColor(1.0f, 0.0f, 0.0f, 1.0f);2086glClearDepthf(1.0f);2087glClearStencil(0x55);2088glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);2089EXPECT_GL_NO_ERROR();20902091// Verify that every color attachment is cleared correctly.2092for (GLint colorIndex = 0; colorIndex < maxDrawBuffers; ++colorIndex)2093{2094glReadBuffer(GL_COLOR_ATTACHMENT0 + colorIndex);20952096EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);2097EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::red);2098EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red);2099EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red);2100}21012102// Verify that depth and stencil attachments are cleared correctly.2103GLFramebuffer fbVerify;2104glBindFramebuffer(GL_FRAMEBUFFER, fbVerify);21052106glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color[0]);2107glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,2108depthStencil);21092110// If depth is not cleared to 1, rendering would fail.2111glDepthFunc(GL_LESS);21122113// If stencil is not cleared to 0x55, rendering would fail.2114glStencilFunc(GL_EQUAL, 0x55, 0xFF);2115glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);21162117// Draw green.2118ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());2119drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.95f);21202121// Verify that green was drawn.2122EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);2123EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);2124EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);2125EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);2126}21272128// Test that mixed masked clear works after clear.2129TEST_P(ClearTestES3, ClearThenMixedMaskedClear)2130{2131constexpr GLsizei kSize = 16;21322133// Setup framebuffer.2134GLRenderbuffer color;2135glBindRenderbuffer(GL_RENDERBUFFER, color);2136glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);21372138GLRenderbuffer depthStencil;2139glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);2140glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);21412142GLFramebuffer fb;2143glBindFramebuffer(GL_FRAMEBUFFER, fb);2144glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color);2145glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,2146depthStencil);2147EXPECT_GL_NO_ERROR();2148ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);21492150// Clear color and depth/stencil2151glClearColor(0.1f, 1.0f, 0.0f, 0.7f);2152glClearDepthf(0.0f);2153glClearStencil(0x55);2154glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);21552156// Clear again, but with color and stencil masked2157glClearColor(1.0f, 0.2f, 0.6f, 1.0f);2158glClearDepthf(1.0f);2159glClearStencil(0x3C);2160glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);2161glStencilMask(0xF0);2162glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);21632164// Issue a draw call to verify color, depth and stencil.21652166// If depth is not cleared to 1, rendering would fail.2167glEnable(GL_DEPTH_TEST);2168glDepthFunc(GL_LESS);21692170// If stencil is not cleared to 0x35, rendering would fail.2171glEnable(GL_STENCIL_TEST);2172glStencilFunc(GL_EQUAL, 0x35, 0xFF);2173glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);2174glStencilMask(0xFF);2175glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);21762177ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());2178glUseProgram(drawColor);2179GLint colorUniformLocation =2180glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());2181ASSERT_NE(colorUniformLocation, -1);21822183// Blend half-transparent blue into the color buffer.2184glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 0.5f);2185glEnable(GL_BLEND);2186glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);2187drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.95f);2188ASSERT_GL_NO_ERROR();21892190// Verify that the color buffer is now gray2191const GLColor kExpected(127, 127, 127, 191);2192EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);2193EXPECT_PIXEL_COLOR_NEAR(0, kSize - 1, kExpected, 1);2194EXPECT_PIXEL_COLOR_NEAR(kSize - 1, 0, kExpected, 1);2195EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected, 1);2196}21972198// Test that draw without state change after masked clear works2199TEST_P(ClearTestES3, DrawClearThenDrawWithoutStateChange)2200{2201swapBuffers();2202constexpr GLsizei kSize = 16;22032204// Setup framebuffer.2205GLRenderbuffer color;2206glBindRenderbuffer(GL_RENDERBUFFER, color);2207glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);22082209GLFramebuffer fb;2210glBindFramebuffer(GL_FRAMEBUFFER, fb);2211glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color);2212EXPECT_GL_NO_ERROR();2213ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);22142215// Clear color initially.2216glClearColor(0.0f, 0.0f, 0.0f, 1.0f);2217glClear(GL_COLOR_BUFFER_BIT);22182219// Mask color.2220glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);22212222ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());2223glUseProgram(drawColor);2224GLint colorUniformLocation =2225glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());2226ASSERT_NE(colorUniformLocation, -1);22272228// Initialize position attribute.2229GLint posLoc = glGetAttribLocation(drawColor, essl1_shaders::PositionAttrib());2230ASSERT_NE(-1, posLoc);2231setupQuadVertexBuffer(0.5f, 1.0f);2232glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);2233glEnableVertexAttribArray(posLoc);22342235// Draw red.2236glViewport(0, 0, kSize, kSize);2237glClearColor(0.0f, 1.0f, 0.0f, 0.0f);2238glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 0.5f);2239glDrawArrays(GL_TRIANGLES, 0, 6);22402241// Clear to green without any state change.2242glClear(GL_COLOR_BUFFER_BIT);22432244// Draw red again without any state change.2245glDrawArrays(GL_TRIANGLES, 0, 6);22462247// Verify that the color buffer is now red2248EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);2249EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::red);2250EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red);2251EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red);2252}22532254// Test that clear stencil value is correctly masked to 8 bits.2255TEST_P(ClearTest, ClearStencilMask)2256{2257GLint stencilBits = 0;2258glGetIntegerv(GL_STENCIL_BITS, &stencilBits);2259EXPECT_EQ(stencilBits, 8);22602261ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());2262glUseProgram(drawColor);22632264glClearColor(0, 0, 0, 1);2265glClear(GL_COLOR_BUFFER_BIT);2266EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);22672268// Clear stencil value must be masked to 0x422269glClearStencil(0x142);2270glClear(GL_STENCIL_BUFFER_BIT);22712272// Check that the stencil test works as expected2273glEnable(GL_STENCIL_TEST);22742275// Negative case2276glStencilFunc(GL_NOTEQUAL, 0x42, 0xFF);2277drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);2278EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);22792280// Positive case2281glStencilFunc(GL_EQUAL, 0x42, 0xFF);2282drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);2283EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);22842285ASSERT_GL_NO_ERROR();2286}22872288// Test that glClearBufferiv correctly masks the clear stencil value.2289TEST_P(ClearTestES3, ClearBufferivStencilMask)2290{2291GLint stencilBits = 0;2292glGetIntegerv(GL_STENCIL_BITS, &stencilBits);2293EXPECT_EQ(stencilBits, 8);22942295ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());2296glUseProgram(drawColor);22972298glClearColor(0, 0, 0, 1);2299glClear(GL_COLOR_BUFFER_BIT);2300EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);23012302// Clear stencil value must be masked to 0x422303const GLint kStencilClearValue = 0x142;2304glClearBufferiv(GL_STENCIL, 0, &kStencilClearValue);23052306// Check that the stencil test works as expected2307glEnable(GL_STENCIL_TEST);23082309// Negative case2310glStencilFunc(GL_NOTEQUAL, 0x42, 0xFF);2311drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);2312EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);23132314// Positive case2315glStencilFunc(GL_EQUAL, 0x42, 0xFF);2316drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);2317EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);23182319ASSERT_GL_NO_ERROR();2320}23212322// Test that glClearBufferfi correctly masks the clear stencil value.2323TEST_P(ClearTestES3, ClearBufferfiStencilMask)2324{2325GLint stencilBits = 0;2326glGetIntegerv(GL_STENCIL_BITS, &stencilBits);2327EXPECT_EQ(stencilBits, 8);23282329ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());2330glUseProgram(drawColor);23312332glClearColor(0, 0, 0, 1);2333glClear(GL_COLOR_BUFFER_BIT);2334EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);23352336// Clear stencil value must be masked to 0x422337glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.5f, 0x142);23382339// Check that the stencil test works as expected2340glEnable(GL_STENCIL_TEST);23412342// Negative case2343glStencilFunc(GL_NOTEQUAL, 0x42, 0xFF);2344drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);2345EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);23462347// Positive case2348glStencilFunc(GL_EQUAL, 0x42, 0xFF);2349drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);2350EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);23512352ASSERT_GL_NO_ERROR();2353}23542355// Test that glClearBufferfi works when stencil attachment is not present.2356TEST_P(ClearTestES3, ClearBufferfiNoStencilAttachment)2357{2358constexpr GLsizei kSize = 16;23592360GLRenderbuffer color;2361glBindRenderbuffer(GL_RENDERBUFFER, color);2362glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);23632364GLRenderbuffer depth;2365glBindRenderbuffer(GL_RENDERBUFFER, depth);2366glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, kSize, kSize);23672368GLFramebuffer fbo;2369glBindFramebuffer(GL_FRAMEBUFFER, fbo);2370glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color);2371glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);2372EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);2373EXPECT_GL_NO_ERROR();23742375// Clear depth/stencil with glClearBufferfi. Note that the stencil attachment doesn't exist.2376glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.5f, 0x55);2377EXPECT_GL_NO_ERROR();23782379// Verify depth is cleared correctly.2380verifyDepth(0.5f, kSize);2381}23822383// Test that scissored clear followed by non-scissored draw works. Ensures that when scissor size2384// is expanded, the clear operation remains limited to the scissor region. Written to catch2385// potential future bugs if loadOp=CLEAR is used in the Vulkan backend for a small render pass and2386// then the render area is mistakenly enlarged.2387TEST_P(ClearTest, ScissoredClearThenNonScissoredDraw)2388{2389constexpr GLsizei kSize = 16;2390const std::vector<GLColor> kInitialData(kSize * kSize, GLColor::red);23912392// Setup framebuffer. Initialize color with red.2393GLTexture color;2394glBindTexture(GL_TEXTURE_2D, color);2395glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,2396kInitialData.data());23972398GLFramebuffer fb;2399glBindFramebuffer(GL_FRAMEBUFFER, fb);2400glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);2401EXPECT_GL_NO_ERROR();2402ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);24032404// Issue a scissored clear to green.2405glClearColor(0.0f, 1.0f, 0.0f, 1.0f);2406glScissor(kSize / 2, 0, kSize / 2, kSize);2407glEnable(GL_SCISSOR_TEST);2408glClear(GL_COLOR_BUFFER_BIT);24092410// Expand the scissor and blend blue into the framebuffer.2411glScissor(0, 0, kSize, kSize);2412glEnable(GL_BLEND);2413glBlendFunc(GL_ONE, GL_ONE);24142415ANGLE_GL_PROGRAM(drawBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());2416drawQuad(drawBlue, essl1_shaders::PositionAttrib(), 0.5f);2417ASSERT_GL_NO_ERROR();24182419// Verify that the left half is magenta, and the right half is cyan.2420EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);2421EXPECT_PIXEL_COLOR_EQ(kSize / 2 - 1, 0, GLColor::magenta);2422EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::magenta);2423EXPECT_PIXEL_COLOR_EQ(kSize / 2 - 1, kSize - 1, GLColor::magenta);24242425EXPECT_PIXEL_COLOR_EQ(kSize / 2, 0, GLColor::cyan);2426EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize - 1, GLColor::cyan);2427EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::cyan);2428EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::cyan);2429}24302431// Test that clear followed by a scissored masked clear works.2432TEST_P(ClearTest, ClearThenScissoredMaskedClear)2433{2434constexpr GLsizei kSize = 16;24352436// Setup framebuffer2437GLTexture color;2438glBindTexture(GL_TEXTURE_2D, color);2439glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);24402441GLFramebuffer fb;2442glBindFramebuffer(GL_FRAMEBUFFER, fb);2443glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);2444EXPECT_GL_NO_ERROR();2445ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);24462447// Clear to red.2448glClearColor(1.0f, 0.0f, 0.0f, 1.0f);2449glClear(GL_COLOR_BUFFER_BIT);24502451// Mask red and clear to green with a scissor2452glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);2453glScissor(0, 0, kSize / 2, kSize);2454glEnable(GL_SCISSOR_TEST);2455glClearColor(0.0f, 1.0f, 0.0f, 1.0f);2456glClear(GL_COLOR_BUFFER_BIT);24572458// Verify that the left half is yellow, and the right half is red.2459EXPECT_PIXEL_RECT_EQ(0, 0, kSize / 2, kSize, GLColor::yellow);2460EXPECT_PIXEL_RECT_EQ(kSize / 2, 0, kSize / 2, kSize, GLColor::red);2461}24622463// This is a test that must be verified visually.2464//2465// Tests that clear of the default framebuffer applies to the window.2466TEST_P(ClearTest, DISABLED_ClearReachesWindow)2467{2468ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());24692470// Draw blue.2471drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);2472swapBuffers();24732474// Use glClear to clear to red. Regression test for the Vulkan backend where this clear2475// remained "deferred" and didn't make it to the window on swap.2476glClearColor(1.0f, 0.0f, 0.0f, 1.0f);2477glClear(GL_COLOR_BUFFER_BIT);2478swapBuffers();24792480// Wait for visual verification.2481angle::Sleep(2000);2482}24832484// Test that clearing slices of a 3D texture and reading them back works.2485TEST_P(ClearTestES3, ClearAndReadPixels3DTexture)2486{2487constexpr uint32_t kWidth = 128;2488constexpr uint32_t kHeight = 128;2489constexpr uint32_t kDepth = 7;24902491GLTexture texture;2492glBindTexture(GL_TEXTURE_3D, texture);2493glTexStorage3D(GL_TEXTURE_3D, 1, GL_RGBA8, kWidth, kHeight, kDepth);2494glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);24952496std::array<GLColor, kDepth> clearColors = {2497GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow,2498GLColor::cyan, GLColor::magenta, GLColor::white,2499};25002501GLFramebuffer framebuffer;2502glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);25032504for (uint32_t z = 0; z < kDepth; ++z)2505{2506glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, z);2507glClearBufferfv(GL_COLOR, 0, clearColors[z].toNormalizedVector().data());2508}25092510for (uint32_t z = 0; z < kDepth; ++z)2511{2512glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, z);2513EXPECT_PIXEL_COLOR_EQ(0, 0, clearColors[z]);2514}2515}25162517#ifdef Bool2518// X11 craziness.2519# undef Bool2520#endif25212522ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ClearTest);25232524GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ClearTestES3);2525ANGLE_INSTANTIATE_TEST_ES3(ClearTestES3);25262527ANGLE_INSTANTIATE_TEST_COMBINE_4(MaskedScissoredClearTest,2528MaskedScissoredClearVariationsTestPrint,2529testing::Range(0, 3),2530testing::Range(0, 3),2531testing::Range(0, 3),2532testing::Bool(),2533ES2_D3D9(),2534ES2_D3D11(),2535ES3_D3D11(),2536ES2_OPENGL(),2537ES3_OPENGL(),2538ES2_OPENGLES(),2539ES3_OPENGLES(),2540ES2_VULKAN(),2541ES3_VULKAN(),2542ES2_METAL(),2543ES3_METAL());25442545GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VulkanClearTest);2546ANGLE_INSTANTIATE_TEST_COMBINE_4(VulkanClearTest,2547MaskedScissoredClearVariationsTestPrint,2548testing::Range(0, 3),2549testing::Range(0, 3),2550testing::Range(0, 3),2551testing::Bool(),2552ES2_VULKAN(),2553ES3_VULKAN());25542555// Not all ANGLE backends support RGB backbuffers2556GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ClearTestRGB);2557ANGLE_INSTANTIATE_TEST(ClearTestRGB,2558ES2_D3D11(),2559ES3_D3D11(),2560ES2_VULKAN(),2561ES3_VULKAN(),2562ES2_METAL(),2563ES3_METAL());25642565} // anonymous namespace256625672568