Path: blob/main_old/src/tests/gl_tests/BlitFramebufferANGLETest.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"7#include "test_utils/gl_raii.h"89using namespace angle;1011namespace12{13class BlitFramebufferANGLETest : public ANGLETest14{15protected:16BlitFramebufferANGLETest()17{18setWindowWidth(64);19setWindowHeight(32);20setConfigRedBits(8);21setConfigGreenBits(8);22setConfigBlueBits(8);23setConfigAlphaBits(8);24setConfigDepthBits(24);25setConfigStencilBits(8);2627mCheckerProgram = 0;28mBlueProgram = 0;29mRedProgram = 0;3031mOriginalFBO = 0;3233mUserFBO = 0;34mUserColorBuffer = 0;35mUserDepthStencilBuffer = 0;3637mSmallFBO = 0;38mSmallColorBuffer = 0;39mSmallDepthStencilBuffer = 0;4041mColorOnlyFBO = 0;42mColorOnlyColorBuffer = 0;4344mDiffFormatFBO = 0;45mDiffFormatColorBuffer = 0;4647mDiffSizeFBO = 0;48mDiffSizeColorBuffer = 0;4950mMRTFBO = 0;51mMRTColorBuffer0 = 0;52mMRTColorBuffer1 = 0;5354mRGBAColorbuffer = 0;55mRGBAFBO = 0;56mRGBAMultisampledRenderbuffer = 0;57mRGBAMultisampledFBO = 0;5859mBGRAColorbuffer = 0;60mBGRAFBO = 0;61mBGRAMultisampledRenderbuffer = 0;62mBGRAMultisampledFBO = 0;63}6465void testSetUp() override66{67mCheckerProgram =68CompileProgram(essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Checkered());69mBlueProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());70mRedProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());71if (mCheckerProgram == 0 || mBlueProgram == 0 || mRedProgram == 0)72{73FAIL() << "shader compilation failed.";74}7576EXPECT_GL_NO_ERROR();7778GLint originalFBO;79glGetIntegerv(GL_FRAMEBUFFER_BINDING, &originalFBO);80if (originalFBO >= 0)81{82mOriginalFBO = (GLuint)originalFBO;83}8485GLenum format = GL_RGBA;8687glGenFramebuffers(1, &mUserFBO);88glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);89glGenTextures(1, &mUserColorBuffer);90glGenRenderbuffers(1, &mUserDepthStencilBuffer);91glBindTexture(GL_TEXTURE_2D, mUserColorBuffer);92glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,93mUserColorBuffer, 0);94glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth(), getWindowHeight(), 0, format,95GL_UNSIGNED_BYTE, nullptr);96glBindRenderbuffer(GL_RENDERBUFFER, mUserDepthStencilBuffer);97glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, getWindowWidth(),98getWindowHeight());99glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,100mUserDepthStencilBuffer);101glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,102mUserDepthStencilBuffer);103104ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));105ASSERT_GL_NO_ERROR();106107glGenFramebuffers(1, &mSmallFBO);108glBindFramebuffer(GL_FRAMEBUFFER, mSmallFBO);109glGenTextures(1, &mSmallColorBuffer);110glGenRenderbuffers(1, &mSmallDepthStencilBuffer);111glBindTexture(GL_TEXTURE_2D, mSmallColorBuffer);112glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth() / 2, getWindowHeight() / 2, 0,113format, GL_UNSIGNED_BYTE, nullptr);114glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,115mSmallColorBuffer, 0);116glBindRenderbuffer(GL_RENDERBUFFER, mSmallDepthStencilBuffer);117glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, getWindowWidth() / 2,118getWindowHeight() / 2);119glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,120mSmallDepthStencilBuffer);121glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,122mSmallDepthStencilBuffer);123124ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));125ASSERT_GL_NO_ERROR();126127glGenFramebuffers(1, &mColorOnlyFBO);128glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO);129glGenTextures(1, &mColorOnlyColorBuffer);130glBindTexture(GL_TEXTURE_2D, mColorOnlyColorBuffer);131glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth(), getWindowHeight(), 0, format,132GL_UNSIGNED_BYTE, nullptr);133glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,134mColorOnlyColorBuffer, 0);135136ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));137ASSERT_GL_NO_ERROR();138139glGenFramebuffers(1, &mDiffFormatFBO);140glBindFramebuffer(GL_FRAMEBUFFER, mDiffFormatFBO);141glGenTextures(1, &mDiffFormatColorBuffer);142glBindTexture(GL_TEXTURE_2D, mDiffFormatColorBuffer);143glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB,144GL_UNSIGNED_SHORT_5_6_5, nullptr);145glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,146mDiffFormatColorBuffer, 0);147148ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));149ASSERT_GL_NO_ERROR();150151glGenFramebuffers(1, &mDiffSizeFBO);152glBindFramebuffer(GL_FRAMEBUFFER, mDiffSizeFBO);153glGenTextures(1, &mDiffSizeColorBuffer);154glBindTexture(GL_TEXTURE_2D, mDiffSizeColorBuffer);155glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth() * 2, getWindowHeight() * 2, 0,156format, GL_UNSIGNED_BYTE, nullptr);157glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,158mDiffSizeColorBuffer, 0);159160ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));161ASSERT_GL_NO_ERROR();162163if (IsGLExtensionEnabled("GL_EXT_draw_buffers"))164{165glGenFramebuffers(1, &mMRTFBO);166glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO);167glGenTextures(1, &mMRTColorBuffer0);168glGenTextures(1, &mMRTColorBuffer1);169glBindTexture(GL_TEXTURE_2D, mMRTColorBuffer0);170glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth(), getWindowHeight(), 0, format,171GL_UNSIGNED_BYTE, nullptr);172glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,173mMRTColorBuffer0, 0);174glBindTexture(GL_TEXTURE_2D, mMRTColorBuffer1);175glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth(), getWindowHeight(), 0, format,176GL_UNSIGNED_BYTE, nullptr);177glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D,178mMRTColorBuffer1, 0);179180ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));181ASSERT_GL_NO_ERROR();182}183184if (IsGLExtensionEnabled("GL_ANGLE_framebuffer_multisample") &&185IsGLExtensionEnabled("GL_OES_rgb8_rgba8"))186{187// RGBA single-sampled framebuffer188glGenTextures(1, &mRGBAColorbuffer);189glBindTexture(GL_TEXTURE_2D, mRGBAColorbuffer);190glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,191GL_UNSIGNED_BYTE, nullptr);192193glGenFramebuffers(1, &mRGBAFBO);194glBindFramebuffer(GL_FRAMEBUFFER, mRGBAFBO);195glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,196mRGBAColorbuffer, 0);197198ASSERT_GL_NO_ERROR();199ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));200201// RGBA multisampled framebuffer202glGenRenderbuffers(1, &mRGBAMultisampledRenderbuffer);203glBindRenderbuffer(GL_RENDERBUFFER, mRGBAMultisampledRenderbuffer);204glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 1, GL_RGBA8, getWindowWidth(),205getWindowHeight());206207glGenFramebuffers(1, &mRGBAMultisampledFBO);208glBindFramebuffer(GL_FRAMEBUFFER, mRGBAMultisampledFBO);209glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,210mRGBAMultisampledRenderbuffer);211212ASSERT_GL_NO_ERROR();213ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));214215if (IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))216{217// BGRA single-sampled framebuffer218glGenTextures(1, &mBGRAColorbuffer);219glBindTexture(GL_TEXTURE_2D, mBGRAColorbuffer);220glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, getWindowWidth(), getWindowHeight(), 0,221GL_BGRA_EXT, GL_UNSIGNED_BYTE, nullptr);222223glGenFramebuffers(1, &mBGRAFBO);224glBindFramebuffer(GL_FRAMEBUFFER, mBGRAFBO);225glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,226mBGRAColorbuffer, 0);227228ASSERT_GL_NO_ERROR();229ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));230231// BGRA multisampled framebuffer232glGenRenderbuffers(1, &mBGRAMultisampledRenderbuffer);233glBindRenderbuffer(GL_RENDERBUFFER, mBGRAMultisampledRenderbuffer);234glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 1, GL_BGRA8_EXT,235getWindowWidth(), getWindowHeight());236237glGenFramebuffers(1, &mBGRAMultisampledFBO);238glBindFramebuffer(GL_FRAMEBUFFER, mBGRAMultisampledFBO);239glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,240mBGRAMultisampledRenderbuffer);241242ASSERT_GL_NO_ERROR();243ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));244}245}246247glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);248}249250void testTearDown() override251{252glDeleteProgram(mCheckerProgram);253glDeleteProgram(mBlueProgram);254glDeleteProgram(mRedProgram);255256glDeleteFramebuffers(1, &mUserFBO);257glDeleteTextures(1, &mUserColorBuffer);258glDeleteRenderbuffers(1, &mUserDepthStencilBuffer);259260glDeleteFramebuffers(1, &mSmallFBO);261glDeleteTextures(1, &mSmallColorBuffer);262glDeleteRenderbuffers(1, &mSmallDepthStencilBuffer);263264glDeleteFramebuffers(1, &mColorOnlyFBO);265glDeleteTextures(1, &mSmallDepthStencilBuffer);266267glDeleteFramebuffers(1, &mDiffFormatFBO);268glDeleteTextures(1, &mDiffFormatColorBuffer);269270glDeleteFramebuffers(1, &mDiffSizeFBO);271glDeleteTextures(1, &mDiffSizeColorBuffer);272273if (IsGLExtensionEnabled("GL_EXT_draw_buffers"))274{275glDeleteFramebuffers(1, &mMRTFBO);276glDeleteTextures(1, &mMRTColorBuffer0);277glDeleteTextures(1, &mMRTColorBuffer1);278}279280if (mRGBAColorbuffer != 0)281{282glDeleteTextures(1, &mRGBAColorbuffer);283}284285if (mRGBAFBO != 0)286{287glDeleteFramebuffers(1, &mRGBAFBO);288}289290if (mRGBAMultisampledRenderbuffer != 0)291{292glDeleteRenderbuffers(1, &mRGBAMultisampledRenderbuffer);293}294295if (mRGBAMultisampledFBO != 0)296{297glDeleteFramebuffers(1, &mRGBAMultisampledFBO);298}299300if (mBGRAColorbuffer != 0)301{302glDeleteTextures(1, &mBGRAColorbuffer);303}304305if (mBGRAFBO != 0)306{307glDeleteFramebuffers(1, &mBGRAFBO);308}309310if (mBGRAMultisampledRenderbuffer != 0)311{312glDeleteRenderbuffers(1, &mBGRAMultisampledRenderbuffer);313}314315if (mBGRAMultisampledFBO != 0)316{317glDeleteFramebuffers(1, &mBGRAMultisampledFBO);318}319}320321void multisampleTestHelper(GLuint readFramebuffer, GLuint drawFramebuffer)322{323glClearColor(0.0, 1.0, 0.0, 1.0);324glBindFramebuffer(GL_DRAW_FRAMEBUFFER, readFramebuffer);325glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);326EXPECT_GL_NO_ERROR();327328glBindFramebuffer(GL_READ_FRAMEBUFFER, readFramebuffer);329glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFramebuffer);330glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),331getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);332EXPECT_GL_NO_ERROR();333334glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFramebuffer);335EXPECT_PIXEL_EQ(getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);336EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);337EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);338EXPECT_PIXEL_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);339}340341bool checkExtension(const std::string &extension)342{343if (!IsGLExtensionEnabled(extension))344{345std::cout << "Test skipped because " << extension << " not supported." << std::endl;346return false;347}348349return true;350}351352GLuint mCheckerProgram;353GLuint mBlueProgram;354GLuint mRedProgram;355356GLuint mOriginalFBO;357358GLuint mUserFBO;359GLuint mUserColorBuffer;360GLuint mUserDepthStencilBuffer;361362GLuint mSmallFBO;363GLuint mSmallColorBuffer;364GLuint mSmallDepthStencilBuffer;365366GLuint mColorOnlyFBO;367GLuint mColorOnlyColorBuffer;368369GLuint mDiffFormatFBO;370GLuint mDiffFormatColorBuffer;371372GLuint mDiffSizeFBO;373GLuint mDiffSizeColorBuffer;374375GLuint mMRTFBO;376GLuint mMRTColorBuffer0;377GLuint mMRTColorBuffer1;378379GLuint mRGBAColorbuffer;380GLuint mRGBAFBO;381GLuint mRGBAMultisampledRenderbuffer;382GLuint mRGBAMultisampledFBO;383384GLuint mBGRAColorbuffer;385GLuint mBGRAFBO;386GLuint mBGRAMultisampledRenderbuffer;387GLuint mBGRAMultisampledFBO;388};389390// Draw to user-created framebuffer, blit whole-buffer color to original framebuffer.391TEST_P(BlitFramebufferANGLETest, BlitColorToDefault)392{393ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));394395glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);396397glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);398399drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);400401EXPECT_GL_NO_ERROR();402403glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);404glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);405406glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),407getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);408409EXPECT_GL_NO_ERROR();410411glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);412413EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);414EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);415EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);416EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);417}418419// Blit color to/from default framebuffer with Flip-X/Flip-Y.420TEST_P(BlitFramebufferANGLETest, BlitColorWithFlip)421{422// OpenGL ES 3.0 / GL_NV_framebuffer_blit required for flip.423ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&424!IsGLExtensionEnabled("GL_NV_framebuffer_blit"));425426glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);427428glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);429430drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);431432EXPECT_GL_NO_ERROR();433434// Blit to default with x-flip.435glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);436glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);437438glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), getWindowWidth(), 0, 0,439getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);440441EXPECT_GL_NO_ERROR();442443glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);444445EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);446EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);447EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);448EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);449450// Blit to default with y-flip.451glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);452glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);453454glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);455glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, getWindowHeight(),456getWindowWidth(), 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);457458EXPECT_GL_NO_ERROR();459460glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);461462EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::green);463EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::red);464EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::yellow);465EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);466467// Blit from default with x-flip.468469glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);470glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);471472glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);473glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), getWindowWidth(), 0, 0,474getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);475476EXPECT_GL_NO_ERROR();477478glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);479480EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::yellow);481EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);482EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::green);483EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::red);484485// Blit from default with y-flip.486glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);487glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);488489glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);490glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, getWindowHeight(),491getWindowWidth(), 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);492493EXPECT_GL_NO_ERROR();494495glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);496497EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);498EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);499EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);500EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);501}502503// Draw to system framebuffer, blit whole-buffer color to user-created framebuffer.504TEST_P(BlitFramebufferANGLETest, ReverseColorBlit)505{506ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));507508// TODO(jmadill): Fix this. http://anglebug.com/2743509ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());510511glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);512513glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);514515drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);516517EXPECT_GL_NO_ERROR();518519glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);520glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);521522glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),523getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);524525EXPECT_GL_NO_ERROR();526527glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);528529EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);530EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);531EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);532EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);533}534535// blit from user-created FBO to system framebuffer, with the scissor test enabled.536TEST_P(BlitFramebufferANGLETest, ScissoredBlit)537{538ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));539540glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);541542glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);543544drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);545546EXPECT_GL_NO_ERROR();547548glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);549glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);550551glClearColor(1.0, 1.0, 1.0, 1.0);552glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);553554glScissor(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());555glEnable(GL_SCISSOR_TEST);556557glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),558getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);559560EXPECT_GL_NO_ERROR();561562glDisable(GL_SCISSOR_TEST);563564glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);565566EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::white);567EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::white);568EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);569EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);570}571572// blit from system FBO to user-created framebuffer, with the scissor test enabled.573TEST_P(BlitFramebufferANGLETest, ReverseScissoredBlit)574{575ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));576577glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);578579glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);580581drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);582583EXPECT_GL_NO_ERROR();584585glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);586glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);587588glClearColor(1.0, 1.0, 1.0, 1.0);589glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);590591glScissor(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());592glEnable(GL_SCISSOR_TEST);593594glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),595getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);596597EXPECT_GL_NO_ERROR();598599glDisable(GL_SCISSOR_TEST);600601glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);602603EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::white);604EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::white);605EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);606EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);607}608609// blit from user-created FBO to system framebuffer, using region larger than buffer.610TEST_P(BlitFramebufferANGLETest, OversizedBlit)611{612ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));613614glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);615616glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);617618drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);619620EXPECT_GL_NO_ERROR();621622glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);623glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);624625glClearColor(1.0, 1.0, 1.0, 1.0);626glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);627628glBlitFramebufferANGLE(0, 0, getWindowWidth() * 2, getWindowHeight() * 2, 0, 0,629getWindowWidth() * 2, getWindowHeight() * 2, GL_COLOR_BUFFER_BIT,630GL_NEAREST);631632EXPECT_GL_NO_ERROR();633634glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);635636EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);637EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);638EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);639EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);640}641642// blit from system FBO to user-created framebuffer, using region larger than buffer.643TEST_P(BlitFramebufferANGLETest, ReverseOversizedBlit)644{645ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));646647glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);648649glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);650651drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);652653EXPECT_GL_NO_ERROR();654655glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);656glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);657658glClearColor(1.0, 1.0, 1.0, 1.0);659glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);660661glBlitFramebufferANGLE(0, 0, getWindowWidth() * 2, getWindowHeight() * 2, 0, 0,662getWindowWidth() * 2, getWindowHeight() * 2, GL_COLOR_BUFFER_BIT,663GL_NEAREST);664EXPECT_GL_NO_ERROR();665666glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);667668EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);669EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);670EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);671EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);672}673674// blit from user-created FBO to system framebuffer, with depth buffer.675TEST_P(BlitFramebufferANGLETest, BlitWithDepthUserToDefault)676{677// TODO(http://anglebug.com/6154): glBlitFramebufferANGLE() generates GL_INVALID_OPERATION for678// the ES2_OpenGL backend.679ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsOpenGL());680681ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));682683glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);684685glDepthMask(GL_TRUE);686glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);687688glEnable(GL_DEPTH_TEST);689690EXPECT_GL_NO_ERROR();691692// Clear the first half of the screen693glEnable(GL_SCISSOR_TEST);694glScissor(0, 0, getWindowWidth(), getWindowHeight() / 2);695696glClearDepthf(0.1f);697glClearColor(1.0, 0.0, 0.0, 1.0);698glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);699700// Scissor the second half of the screen701glScissor(0, getWindowHeight() / 2, getWindowWidth(), getWindowHeight() / 2);702703glClearDepthf(0.9f);704glClearColor(0.0, 1.0, 0.0, 1.0);705glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);706707glDisable(GL_SCISSOR_TEST);708709glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);710glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);711712glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),713getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,714GL_NEAREST);715EXPECT_GL_NO_ERROR();716717glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);718719// if blit is happening correctly, this quad will draw only on the bottom half since it will720// be behind on the first half and in front on the second half.721drawQuad(mBlueProgram, essl1_shaders::PositionAttrib(), 0.5f);722723glDisable(GL_DEPTH_TEST);724725EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);726EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);727EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);728EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);729}730731// blit from system FBO to user-created framebuffer, with depth buffer.732TEST_P(BlitFramebufferANGLETest, BlitWithDepthDefaultToUser)733{734ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));735736glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);737738glDepthMask(GL_TRUE);739glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);740741glEnable(GL_DEPTH_TEST);742743EXPECT_GL_NO_ERROR();744745// Clear the first half of the screen746glEnable(GL_SCISSOR_TEST);747glScissor(0, 0, getWindowWidth(), getWindowHeight() / 2);748749glClearDepthf(0.1f);750glClearColor(1.0, 0.0, 0.0, 1.0);751glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);752753// Scissor the second half of the screen754glScissor(0, getWindowHeight() / 2, getWindowWidth(), getWindowHeight() / 2);755756glClearDepthf(0.9f);757glClearColor(0.0, 1.0, 0.0, 1.0);758glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);759760glDisable(GL_SCISSOR_TEST);761762glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);763glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);764765glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),766getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,767GL_NEAREST);768EXPECT_GL_NO_ERROR();769770glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);771772// if blit is happening correctly, this quad will draw only on the bottom half since it will be773// behind on the first half and in front on the second half.774drawQuad(mBlueProgram, essl1_shaders::PositionAttrib(), 0.5f);775776glDisable(GL_DEPTH_TEST);777778EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);779EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);780EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);781EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);782}783784// blit from one region of the system fbo to another-- this should fail.785TEST_P(BlitFramebufferANGLETest, BlitSameBufferOriginal)786{787ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));788789glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);790791glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);792793drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.3f);794795EXPECT_GL_NO_ERROR();796797glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight(), getWindowWidth() / 2, 0,798getWindowWidth(), getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);799EXPECT_GL_ERROR(GL_INVALID_OPERATION);800}801802// blit from one region of the system fbo to another.803TEST_P(BlitFramebufferANGLETest, BlitSameBufferUser)804{805ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));806807glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);808809glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);810811drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.3f);812813EXPECT_GL_NO_ERROR();814815glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight(), getWindowWidth() / 2, 0,816getWindowWidth(), getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);817EXPECT_GL_ERROR(GL_INVALID_OPERATION);818}819820TEST_P(BlitFramebufferANGLETest, BlitPartialColor)821{822ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));823824glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);825826glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);827828drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);829830EXPECT_GL_NO_ERROR();831832glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);833glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);834835glClearColor(1.0, 1.0, 1.0, 1.0);836glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);837838glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0,839getWindowHeight() / 2, getWindowWidth() / 2, getWindowHeight(),840GL_COLOR_BUFFER_BIT, GL_NEAREST);841842EXPECT_GL_NO_ERROR();843844glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);845846EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::white);847EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::red);848EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::white);849EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::white);850}851852TEST_P(BlitFramebufferANGLETest, BlitDifferentSizes)853{854ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));855856glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);857858glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);859860drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);861862EXPECT_GL_NO_ERROR();863864glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mSmallFBO);865glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);866867glClearColor(1.0, 1.0, 1.0, 1.0);868glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);869870glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),871getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);872873EXPECT_GL_NO_ERROR();874875glBindFramebuffer(GL_FRAMEBUFFER, mSmallFBO);876877EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);878879EXPECT_GL_NO_ERROR();880}881882TEST_P(BlitFramebufferANGLETest, BlitWithMissingAttachments)883{884ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));885886glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO);887888glClear(GL_COLOR_BUFFER_BIT);889drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.3f);890891glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);892glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mColorOnlyFBO);893894glClearColor(1.0, 1.0, 1.0, 1.0);895glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);896897// generate INVALID_OPERATION if the read FBO has no depth attachment898glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),899getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,900GL_NEAREST);901902EXPECT_GL_ERROR(GL_INVALID_OPERATION);903904// generate INVALID_OPERATION if the read FBO has no stencil attachment905glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),906getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,907GL_NEAREST);908909EXPECT_GL_ERROR(GL_INVALID_OPERATION);910911// generate INVALID_OPERATION if we read from a missing color attachment912glReadBuffer(GL_COLOR_ATTACHMENT1);913glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),914getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);915916EXPECT_GL_ERROR(GL_INVALID_OPERATION);917}918919TEST_P(BlitFramebufferANGLETest, BlitStencil)920{921ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));922923// http://anglebug.com/2205924ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());925926// http://anglebug.com/4919927ANGLE_SKIP_TEST_IF(IsIntel() && IsMetal());928929// http://anglebug.com/5396930ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D9());931932glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);933934glClearColor(0.0, 1.0, 0.0, 1.0);935glClearStencil(0x0);936glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);937938// Scissor half the screen so we fill the stencil only halfway939glScissor(0, 0, getWindowWidth(), getWindowHeight() / 2);940glEnable(GL_SCISSOR_TEST);941942// fill the stencil buffer with 0x1943glStencilFunc(GL_ALWAYS, 0x1, 0xFF);944glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);945glEnable(GL_STENCIL_TEST);946drawQuad(mRedProgram, essl1_shaders::PositionAttrib(), 0.3f);947948glDisable(GL_SCISSOR_TEST);949950glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);951glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);952953// These clears are not useful in theory because we're copying over them, but its954// helpful in debugging if we see white in any result.955glClearColor(1.0, 1.0, 1.0, 1.0);956glClearStencil(0x0);957glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);958959// depth blit request should be silently ignored, because the read FBO has no depth attachment960glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),961getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,962GL_NEAREST);963964EXPECT_GL_NO_ERROR();965966glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);967968EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);969EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);970EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);971EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);972973glStencilFunc(GL_EQUAL, 0x1, 0xFF); // only pass if stencil buffer at pixel reads 0x1974975drawQuad(mBlueProgram, essl1_shaders::PositionAttrib(),9760.8f); // blue quad will draw if stencil buffer was copied977978glDisable(GL_STENCIL_TEST);979980EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);981EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);982EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);983EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);984}985986// make sure that attempting to blit a partial depth buffer issues an error987TEST_P(BlitFramebufferANGLETest, BlitPartialDepthStencil)988{989ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));990991glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);992993glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);994995drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);996997EXPECT_GL_NO_ERROR();998999glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);1000glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);10011002glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, 0,1003getWindowWidth() / 2, getWindowHeight() / 2, GL_DEPTH_BUFFER_BIT,1004GL_NEAREST);1005EXPECT_GL_ERROR(GL_INVALID_OPERATION);1006}10071008// Test blit with MRT framebuffers1009TEST_P(BlitFramebufferANGLETest, BlitMRT)1010{1011ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));10121013if (!IsGLExtensionEnabled("GL_EXT_draw_buffers"))1014{1015return;1016}10171018GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};10191020glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO);1021glDrawBuffersEXT(2, drawBuffers);10221023glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO);10241025glClear(GL_COLOR_BUFFER_BIT);10261027drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);10281029EXPECT_GL_NO_ERROR();10301031glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mColorOnlyFBO);1032glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mMRTFBO);10331034glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),1035getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);10361037EXPECT_GL_NO_ERROR();10381039glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO);10401041EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);1042EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);1043EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);1044EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);10451046glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, 0, 0);1047glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mMRTColorBuffer0,10480);10491050EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);1051EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);1052EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);1053EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);10541055glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mMRTColorBuffer0,10560);1057glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D,1058mMRTColorBuffer1, 0);1059}10601061// Test multisampled framebuffer blits if supported1062TEST_P(BlitFramebufferANGLETest, MultisampledRGBAToRGBA)1063{1064ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));10651066if (!checkExtension("GL_ANGLE_framebuffer_multisample"))1067return;10681069if (!checkExtension("GL_OES_rgb8_rgba8"))1070return;10711072multisampleTestHelper(mRGBAMultisampledFBO, mRGBAFBO);1073}10741075TEST_P(BlitFramebufferANGLETest, MultisampledRGBAToBGRA)1076{1077ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));10781079// VVL report error http://anglebug.com/46941080ANGLE_SKIP_TEST_IF(IsVulkan());10811082if (!checkExtension("GL_ANGLE_framebuffer_multisample"))1083return;10841085if (!checkExtension("GL_OES_rgb8_rgba8"))1086return;10871088if (!checkExtension("GL_EXT_texture_format_BGRA8888"))1089return;10901091multisampleTestHelper(mRGBAMultisampledFBO, mBGRAFBO);1092}10931094TEST_P(BlitFramebufferANGLETest, MultisampledBGRAToRGBA)1095{1096ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));10971098// VVL report error http://anglebug.com/46941099ANGLE_SKIP_TEST_IF(IsVulkan());11001101if (!checkExtension("GL_ANGLE_framebuffer_multisample"))1102return;11031104if (!checkExtension("GL_OES_rgb8_rgba8"))1105return;11061107if (!checkExtension("GL_EXT_texture_format_BGRA8888"))1108return;11091110multisampleTestHelper(mBGRAMultisampledFBO, mRGBAFBO);1111}11121113TEST_P(BlitFramebufferANGLETest, MultisampledBGRAToBGRA)1114{1115ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));11161117if (!checkExtension("GL_ANGLE_framebuffer_multisample"))1118return;11191120if (!checkExtension("GL_OES_rgb8_rgba8"))1121return;11221123if (!checkExtension("GL_EXT_texture_format_BGRA8888"))1124return;11251126multisampleTestHelper(mBGRAMultisampledFBO, mBGRAFBO);1127}11281129// Make sure that attempts to stretch in a blit call issue an error1130TEST_P(BlitFramebufferANGLETest, ErrorStretching)1131{1132ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));11331134glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);11351136glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);11371138drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);11391140EXPECT_GL_NO_ERROR();11411142glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);1143glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);11441145glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, 0,1146getWindowWidth(), getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);1147EXPECT_GL_ERROR(GL_INVALID_OPERATION);1148}11491150// Make sure that attempts to flip in a blit call issue an error1151TEST_P(BlitFramebufferANGLETest, ErrorFlipping)1152{1153ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));11541155glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);11561157glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);11581159drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);11601161EXPECT_GL_NO_ERROR();11621163glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);1164glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);11651166glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, getWindowWidth() / 2,1167getWindowHeight() / 2, 0, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);1168EXPECT_GL_ERROR(GL_INVALID_OPERATION);1169}11701171TEST_P(BlitFramebufferANGLETest, Errors)1172{1173ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));11741175glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);11761177glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);11781179drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);11801181EXPECT_GL_NO_ERROR();11821183glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);1184glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);11851186glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),1187getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_LINEAR);1188EXPECT_GL_ERROR(GL_INVALID_ENUM);11891190glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),1191getWindowHeight(), GL_COLOR_BUFFER_BIT | 234, GL_NEAREST);1192EXPECT_GL_ERROR(GL_INVALID_VALUE);11931194glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mDiffFormatFBO);11951196glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),1197getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);1198EXPECT_GL_ERROR(GL_INVALID_OPERATION);1199}12001201// TODO(geofflang): Fix the dependence on glBlitFramebufferANGLE without checks and assuming the1202// default framebuffer is BGRA to enable the GL and GLES backends. (http://anglebug.com/1289)12031204class BlitFramebufferTest : public ANGLETest1205{1206protected:1207BlitFramebufferTest()1208{1209setWindowWidth(256);1210setWindowHeight(256);1211setConfigRedBits(8);1212setConfigGreenBits(8);1213setConfigBlueBits(8);1214setConfigAlphaBits(8);1215setConfigDepthBits(24);1216setConfigStencilBits(8);1217}12181219void initColorFBO(GLFramebuffer *fbo,1220GLRenderbuffer *rbo,1221GLenum rboFormat,1222GLsizei width,1223GLsizei height)1224{1225glBindRenderbuffer(GL_RENDERBUFFER, *rbo);1226glRenderbufferStorage(GL_RENDERBUFFER, rboFormat, width, height);12271228glBindFramebuffer(GL_FRAMEBUFFER, *fbo);1229glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *rbo);1230}12311232void initColorFBOWithCheckerPattern(GLFramebuffer *fbo,1233GLRenderbuffer *rbo,1234GLenum rboFormat,1235GLsizei width,1236GLsizei height)1237{1238initColorFBO(fbo, rbo, rboFormat, width, height);12391240ANGLE_GL_PROGRAM(checkerProgram, essl1_shaders::vs::Passthrough(),1241essl1_shaders::fs::Checkered());1242glViewport(0, 0, width, height);1243glBindFramebuffer(GL_FRAMEBUFFER, *fbo);1244drawQuad(checkerProgram.get(), essl1_shaders::PositionAttrib(), 0.5f);1245}1246};12471248class BlitFramebufferTestES31 : public BlitFramebufferTest1249{};12501251// Tests resolving a multisample depth buffer.1252TEST_P(BlitFramebufferTest, MultisampleDepth)1253{1254// Test failure introduced by Apple's changes (anglebug.com/5505)1255ANGLE_SKIP_TEST_IF(IsMetal());12561257// TODO([email protected]): http://crbug.com/8377171258ANGLE_SKIP_TEST_IF(IsOpenGL() && IsOSX());12591260GLRenderbuffer renderbuf;1261glBindRenderbuffer(GL_RENDERBUFFER, renderbuf.get());1262glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT24, 256, 256);12631264GLFramebuffer framebuffer;1265glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());1266glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,1267renderbuf.get());12681269ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));12701271glClearDepthf(0.5f);1272glClear(GL_DEPTH_BUFFER_BIT);12731274GLRenderbuffer destRenderbuf;1275glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf.get());1276glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 256, 256);12771278GLFramebuffer resolved;1279glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved.get());1280glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,1281destRenderbuf.get());12821283glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());1284glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_DEPTH_BUFFER_BIT, GL_NEAREST);12851286glBindFramebuffer(GL_FRAMEBUFFER, resolved.get());12871288GLTexture colorbuf;1289glBindTexture(GL_TEXTURE_2D, colorbuf.get());1290glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);1291glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuf.get(), 0);12921293ASSERT_GL_NO_ERROR();12941295// Clear to green1296glClearColor(0.0f, 1.0f, 0.0f, 1.0f);1297glClear(GL_COLOR_BUFFER_BIT);1298EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);12991300// Make sure resulting depth is near 0.5f.1301ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());1302glEnable(GL_DEPTH_TEST);1303glDepthMask(false);1304glDepthFunc(GL_LESS);1305drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), -0.01f);1306EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);1307EXPECT_PIXEL_COLOR_EQ(255, 0, GLColor::red);1308EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::red);1309EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor::red);1310EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::red);13111312ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());1313glEnable(GL_DEPTH_TEST);1314glDepthMask(false);1315glDepthFunc(GL_GREATER);1316drawQuad(drawBlue.get(), essl3_shaders::PositionAttrib(), 0.01f);1317EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);1318EXPECT_PIXEL_COLOR_EQ(255, 0, GLColor::blue);1319EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::blue);1320EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor::blue);1321EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::blue);13221323ASSERT_GL_NO_ERROR();1324}13251326// Blit multisample stencil buffer to default framebuffer without prerotaion.1327TEST_P(BlitFramebufferTest, BlitMultisampleStencilToDefault)1328{1329// http://anglebug.com/34961330ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());13311332// http://anglebug.com/51061333ANGLE_SKIP_TEST_IF(IsMetal() && IsIntel() && IsOSX());13341335glClearColor(0.0f, 0.0f, 0.0f, 1.0f);1336glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);13371338GLRenderbuffer colorbuf;1339glBindRenderbuffer(GL_RENDERBUFFER, colorbuf.get());1340glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, 128, 128);13411342GLRenderbuffer depthstencilbuf;1343glBindRenderbuffer(GL_RENDERBUFFER, depthstencilbuf.get());1344glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, 128, 128);13451346GLFramebuffer framebuffer;1347glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());1348glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);1349glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,1350depthstencilbuf);1351glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,1352depthstencilbuf);1353glCheckFramebufferStatus(GL_FRAMEBUFFER);13541355glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);1356glFlush();13571358// Replace stencil to 1.1359ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());1360glEnable(GL_STENCIL_TEST);1361glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);1362glStencilFunc(GL_ALWAYS, 1, 255);1363drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.8f);13641365// Blit multisample stencil buffer to default frambuffer.1366GLenum attachments1[] = {GL_COLOR_ATTACHMENT0};1367glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments1);1368glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);1369glBlitFramebuffer(0, 0, 128, 128, 0, 0, 128, 128, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,1370GL_NEAREST);1371glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);13721373// Disable stencil and draw full_screen green color.1374ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());1375glDisable(GL_STENCIL_TEST);1376drawQuad(drawGreen.get(), essl3_shaders::PositionAttrib(), 0.5f);13771378// Draw blue color if the stencil is equal to 1.1379// If the blit finished successfully, the stencil test should all pass.1380ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());1381glEnable(GL_STENCIL_TEST);1382glStencilFunc(GL_EQUAL, 1, 255);1383drawQuad(drawBlue.get(), essl3_shaders::PositionAttrib(), 0.2f);13841385// Check the result, especially the boundaries.1386EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);1387EXPECT_PIXEL_COLOR_EQ(127, 0, GLColor::blue);1388EXPECT_PIXEL_COLOR_EQ(50, 0, GLColor::blue);1389EXPECT_PIXEL_COLOR_EQ(127, 1, GLColor::blue);1390EXPECT_PIXEL_COLOR_EQ(0, 127, GLColor::blue);1391EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::blue);1392EXPECT_PIXEL_COLOR_EQ(64, 64, GLColor::blue);13931394ASSERT_GL_NO_ERROR();1395}13961397// Tests clearing a multisampled depth buffer.1398TEST_P(BlitFramebufferTest, MultisampleDepthClear)1399{1400// clearDepth && !maskDepth fails on Intel Ubuntu 19.04 Mesa 19.0.2 GL. http://anglebug.com/36141401ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsDesktopOpenGL());14021403// http://anglebug.com/40921404ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());14051406GLRenderbuffer depthMS;1407glBindRenderbuffer(GL_RENDERBUFFER, depthMS.get());1408glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT24, 256, 256);14091410GLRenderbuffer colorMS;1411glBindRenderbuffer(GL_RENDERBUFFER, colorMS.get());1412glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 256, 256);14131414GLRenderbuffer colorResolved;1415glBindRenderbuffer(GL_RENDERBUFFER, colorResolved.get());1416glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 256, 256);14171418GLFramebuffer framebufferMS;1419glBindFramebuffer(GL_FRAMEBUFFER, framebufferMS.get());1420glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthMS.get());1421glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorMS.get());14221423// Clear depth buffer to 0.5 and color to green.1424glClearDepthf(0.5f);1425glClearColor(0.0f, 1.0f, 0.0f, 1.0f);1426glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);14271428glFlush();14291430// Draw red into the multisampled color buffer.1431ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());1432glEnable(GL_DEPTH_TEST);1433glDepthFunc(GL_EQUAL);1434drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.0f);14351436// Resolve the color buffer to make sure the above draw worked correctly, which in turn implies1437// that the multisampled depth clear worked.1438GLFramebuffer framebufferResolved;1439glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved.get());1440glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,1441colorResolved.get());1442glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferMS.get());1443glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_COLOR_BUFFER_BIT, GL_NEAREST);14441445glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved.get());14461447ASSERT_GL_NO_ERROR();14481449EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);1450EXPECT_PIXEL_COLOR_EQ(255, 0, GLColor::red);1451EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::red);1452EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor::red);1453EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::red);14541455ASSERT_GL_NO_ERROR();1456}14571458// Test resolving a multisampled stencil buffer.1459TEST_P(BlitFramebufferTest, MultisampleStencil)1460{1461// Incorrect rendering results seen on AMD Windows OpenGL. http://anglebug.com/24861462ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL() && IsWindows());14631464// http://anglebug.com/51061465ANGLE_SKIP_TEST_IF(IsMetal() && IsIntel() && IsOSX());14661467GLRenderbuffer renderbuf;1468glBindRenderbuffer(GL_RENDERBUFFER, renderbuf.get());1469glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_STENCIL_INDEX8, 256, 256);14701471ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());14721473GLFramebuffer framebuffer;1474glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());1475glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,1476renderbuf.get());14771478ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));14791480// fill the stencil buffer with 0x11481glStencilFunc(GL_ALWAYS, 0x1, 0xFF);1482glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);1483glEnable(GL_STENCIL_TEST);1484drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);14851486GLTexture destColorbuf;1487glBindTexture(GL_TEXTURE_2D, destColorbuf.get());1488glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);14891490GLRenderbuffer destRenderbuf;1491glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf.get());1492glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 256, 256);14931494GLFramebuffer resolved;1495glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved.get());1496glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,1497destColorbuf.get(), 0);1498glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,1499destRenderbuf.get());15001501glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());1502glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_STENCIL_BUFFER_BIT, GL_NEAREST);15031504glBindFramebuffer(GL_FRAMEBUFFER, resolved.get());15051506ASSERT_GL_NO_ERROR();15071508// Clear to green1509glClearColor(0.0f, 1.0f, 0.0f, 1.0f);1510glClear(GL_COLOR_BUFFER_BIT);1511EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);15121513// Draw red if the stencil is 0x1, which should be true after the resolve.1514glStencilFunc(GL_EQUAL, 0x1, 0xFF);1515drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);1516EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);15171518ASSERT_GL_NO_ERROR();1519}15201521// Test resolving a multisampled stencil buffer with scissor.1522TEST_P(BlitFramebufferTest, ScissoredMultisampleStencil)1523{1524// Incorrect rendering results seen on AMD Windows OpenGL. http://anglebug.com/24861525ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL() && IsWindows());15261527// Fails verifying that the middle pixel is red. http://anglebug.com/34961528ANGLE_SKIP_TEST_IF((IsIntel() || IsAMD()) && IsOSX());15291530constexpr GLuint kSize = 256;15311532// Create the resolve framebuffer.1533GLTexture destColorbuf;1534glBindTexture(GL_TEXTURE_2D, destColorbuf.get());1535glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);15361537GLRenderbuffer destRenderbuf;1538glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf.get());1539glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kSize, kSize);15401541GLFramebuffer resolved;1542glBindFramebuffer(GL_FRAMEBUFFER, resolved.get());1543glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,1544destColorbuf.get(), 0);1545glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,1546destRenderbuf.get());15471548// Clear the resolved buffer with gray and 0x10 stencil.1549GLColor gray(127, 127, 127, 255);1550glClearStencil(0x10);1551glClearColor(0.499f, 0.499f, 0.499f, 1.0f);1552glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);1553EXPECT_PIXEL_COLOR_EQ(0, 0, gray);1554EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);15551556// Create the multisampled framebuffer.1557GLRenderbuffer renderbuf;1558glBindRenderbuffer(GL_RENDERBUFFER, renderbuf.get());1559glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_STENCIL_INDEX8, kSize, kSize);15601561ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());1562ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());1563ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());15641565GLFramebuffer framebuffer;1566glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());1567glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,1568renderbuf.get());15691570ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));15711572// Fill the stencil buffer with 0x1.1573glClearStencil(0x1);1574glClear(GL_STENCIL_BUFFER_BIT);15751576// Fill a smaller region of the buffer with 0x2.1577glEnable(GL_SCISSOR_TEST);1578glEnable(GL_STENCIL_TEST);1579glScissor(kSize / 4, kSize / 4, kSize / 2, kSize / 2);1580glStencilFunc(GL_ALWAYS, 0x2, 0xFF);1581glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);1582drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);15831584// Blit into the resolved framebuffer (with scissor still enabled).1585glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved.get());1586glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_STENCIL_BUFFER_BIT, GL_NEAREST);15871588glBindFramebuffer(GL_FRAMEBUFFER, resolved.get());15891590ASSERT_GL_NO_ERROR();15911592// Draw blue if the stencil is 0x1, which should never be true.1593glDisable(GL_SCISSOR_TEST);1594glStencilMask(0);1595glStencilFunc(GL_EQUAL, 0x1, 0xFF);1596drawQuad(drawBlue.get(), essl3_shaders::PositionAttrib(), 0.5f);1597EXPECT_PIXEL_COLOR_EQ(0, 0, gray);1598EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);1599EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);1600EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);1601EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);16021603// Draw red if the stencil is 0x2, which should be true in the middle after the blit/resolve.1604glStencilFunc(GL_EQUAL, 0x2, 0xFF);1605drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);1606EXPECT_PIXEL_COLOR_EQ(0, 0, gray);1607EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);1608EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);1609EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);1610EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);16111612// Draw green if the stencil is 0x10, which should be left untouched in the outer regions.1613glStencilFunc(GL_EQUAL, 0x10, 0xFF);1614drawQuad(drawGreen.get(), essl3_shaders::PositionAttrib(), 0.5f);1615EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);1616EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);1617EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);1618EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);1619EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);16201621ASSERT_GL_NO_ERROR();1622}16231624// Test blitting from a texture with non-zero base. The blit is non-stretching and between1625// identical formats so that the path that uses vkCmdBlitImage is taken.1626TEST_P(BlitFramebufferTest, NonZeroBaseSource)1627{1628// http://anglebug.com/50011629ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());16301631ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());16321633// Create a framebuffer for source data. It usea a non-zero base.1634GLTexture srcColor;1635glBindTexture(GL_TEXTURE_2D, srcColor);1636glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);1637glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);1638glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);16391640GLFramebuffer srcFramebuffer;1641glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);1642glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcColor, 1);1643ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);16441645// fill the color buffer with red.1646drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);16471648// Create a framebuffer for blit destination.1649GLTexture dstColor;1650glBindTexture(GL_TEXTURE_2D, dstColor);1651glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);16521653GLFramebuffer dstFramebuffer;1654glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);1655glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstColor, 0);1656ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);16571658// Blit. Note: no stretching is done so that vkCmdBlitImage can be used.1659glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);1660glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_COLOR_BUFFER_BIT, GL_NEAREST);16611662glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);16631664ASSERT_GL_NO_ERROR();16651666// Make sure the blit is done.1667EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);16681669ASSERT_GL_NO_ERROR();1670}16711672// Test blitting to a texture with non-zero base. The blit is non-stretching and between1673// identical formats so that the path that uses vkCmdBlitImage is taken.1674TEST_P(BlitFramebufferTest, NonZeroBaseDestination)1675{1676ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());16771678// Create a framebuffer for source data. It usea a non-zero base.1679GLTexture srcColor;1680glBindTexture(GL_TEXTURE_2D, srcColor);1681glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);16821683GLFramebuffer srcFramebuffer;1684glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);1685glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcColor, 0);1686ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);16871688// fill the color buffer with red.1689drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);16901691// Create a framebuffer for blit destination.1692GLTexture dstColor;1693glBindTexture(GL_TEXTURE_2D, dstColor);1694glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);1695glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);1696glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);16971698GLFramebuffer dstFramebuffer;1699glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);1700glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstColor, 1);1701ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);17021703// Blit. Note: no stretching is done so that vkCmdBlitImage can be used.1704glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);1705glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_COLOR_BUFFER_BIT, GL_NEAREST);17061707glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);17081709ASSERT_GL_NO_ERROR();17101711// Make sure the blit is done.1712EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);17131714ASSERT_GL_NO_ERROR();1715}17161717// Test blitting from a stencil buffer with non-zero base.1718TEST_P(BlitFramebufferTest, NonZeroBaseSourceStencil)1719{1720// http://anglebug.com/50011721ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());17221723// http://anglebug.com/51061724ANGLE_SKIP_TEST_IF(IsMetal() && IsIntel() && IsOSX());17251726ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());17271728// Create a framebuffer with an attachment that has non-zero base1729GLTexture stencilTexture;1730glBindTexture(GL_TEXTURE_2D, stencilTexture);1731glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,1732GL_UNSIGNED_INT_24_8, nullptr);1733glTexImage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,1734GL_UNSIGNED_INT_24_8, nullptr);1735glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);17361737GLFramebuffer srcFramebuffer;1738glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);1739glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTexture, 1);1740ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);17411742// fill the stencil buffer with 0x11743glStencilFunc(GL_ALWAYS, 0x1, 0xFF);1744glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);1745glEnable(GL_STENCIL_TEST);1746drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);17471748// Create a framebuffer with an attachment that has non-zero base1749GLTexture colorTexture;1750glBindTexture(GL_TEXTURE_2D, colorTexture);1751glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);17521753GLRenderbuffer renderbuf;1754glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);1755glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 256, 256);17561757GLFramebuffer dstFramebuffer;1758glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);1759glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);1760glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);1761ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);17621763// Blit stencil.1764glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);1765glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_STENCIL_BUFFER_BIT, GL_NEAREST);17661767glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);17681769ASSERT_GL_NO_ERROR();17701771// Clear to green1772glClearColor(0.0f, 1.0f, 0.0f, 1.0f);1773glClear(GL_COLOR_BUFFER_BIT);1774EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);17751776// Draw red if the stencil is 0x1, which should be true after the blit.1777glStencilFunc(GL_EQUAL, 0x1, 0xFF);1778drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);1779EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);17801781ASSERT_GL_NO_ERROR();1782}17831784// Test blitting to a stencil buffer with non-zero base.1785TEST_P(BlitFramebufferTest, NonZeroBaseDestinationStencil)1786{1787// http://anglebug.com/50011788ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());1789// http://anglebug.com/51061790ANGLE_SKIP_TEST_IF(IsMetal() && (IsAMD() || IsIntel()));1791// http://anglebug.com/50031792ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsWindows());17931794ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());17951796// Create a framebuffer for source data.1797GLRenderbuffer renderbuf;1798glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);1799glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 256, 256);18001801GLFramebuffer srcFramebuffer;1802glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);1803glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);1804ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);18051806// fill the stencil buffer with 0x11807glStencilFunc(GL_ALWAYS, 0x1, 0xFF);1808glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);1809glEnable(GL_STENCIL_TEST);1810drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);18111812// Create a framebuffer with an attachment that has non-zero base1813GLTexture colorTexture;1814glBindTexture(GL_TEXTURE_2D, colorTexture);1815glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);18161817GLTexture stencilTexture;1818glBindTexture(GL_TEXTURE_2D, stencilTexture);1819glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,1820GL_UNSIGNED_INT_24_8, nullptr);1821glTexImage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,1822GL_UNSIGNED_INT_24_8, nullptr);1823glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);18241825GLFramebuffer dstFramebuffer;1826glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);1827glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);1828glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTexture, 1);1829ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);18301831// Blit stencil.1832glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);1833glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_STENCIL_BUFFER_BIT, GL_NEAREST);18341835glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);18361837ASSERT_GL_NO_ERROR();18381839// Clear to green1840glClearColor(0.0f, 1.0f, 0.0f, 1.0f);1841glClear(GL_COLOR_BUFFER_BIT);1842EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);18431844// Draw red if the stencil is 0x1, which should be true after the blit.1845glStencilFunc(GL_EQUAL, 0x1, 0xFF);1846drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);1847EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);18481849ASSERT_GL_NO_ERROR();1850}18511852// Test blitting to a stencil buffer with non-zero base. Exercises the compute path in the Vulkan1853// backend if stencil export is not supported. The blit is not 1-to-1 for this path to be taken.1854TEST_P(BlitFramebufferTest, NonZeroBaseDestinationStencilStretch)1855{1856// http://anglebug.com/50001857ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsWindows());18581859// http://anglebug.com/50011860ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());18611862// http://anglebug.com/51061863ANGLE_SKIP_TEST_IF(IsMetal() && (IsAMD() || IsIntel()));18641865ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());18661867// Create a framebuffer for source data.1868GLRenderbuffer renderbuf;1869glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);1870glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 256, 256);18711872GLFramebuffer srcFramebuffer;1873glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);1874glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);1875ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);18761877// fill the stencil buffer with 0x11878glStencilFunc(GL_ALWAYS, 0x1, 0xFF);1879glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);1880glEnable(GL_STENCIL_TEST);1881drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);18821883// Create a framebuffer with an attachment that has non-zero base1884GLTexture colorTexture;1885glBindTexture(GL_TEXTURE_2D, colorTexture);1886glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);18871888GLTexture stencilTexture;1889glBindTexture(GL_TEXTURE_2D, stencilTexture);1890glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,1891GL_UNSIGNED_INT_24_8, nullptr);1892glTexImage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,1893GL_UNSIGNED_INT_24_8, nullptr);1894glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);18951896GLFramebuffer dstFramebuffer;1897glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);1898glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);1899glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTexture, 1);1900ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);19011902// Blit stencil. Note: stretch is intentional so vkCmdBlitImage cannot be used in the Vulkan1903// backend.1904glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);1905glBlitFramebuffer(0, 0, 256, 256, -256, -256, 512, 512, GL_STENCIL_BUFFER_BIT, GL_NEAREST);19061907glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);19081909ASSERT_GL_NO_ERROR();19101911// Clear to green1912glClearColor(0.0f, 1.0f, 0.0f, 1.0f);1913glClear(GL_COLOR_BUFFER_BIT);1914EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);19151916// Draw red if the stencil is 0x1, which should be true after the blit.1917glStencilFunc(GL_EQUAL, 0x1, 0xFF);1918drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);1919EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);19201921ASSERT_GL_NO_ERROR();1922}19231924// Blit an SRGB framebuffer and scale it.1925TEST_P(BlitFramebufferTest, BlitSRGBToRGBAndScale)1926{1927constexpr const GLsizei kWidth = 256;1928constexpr const GLsizei kHeight = 256;19291930GLRenderbuffer sourceRBO, targetRBO;1931GLFramebuffer sourceFBO, targetFBO;1932initColorFBOWithCheckerPattern(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth * 2,1933kHeight * 2);1934initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);19351936EXPECT_GL_NO_ERROR();19371938glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);1939glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);19401941glViewport(0, 0, kWidth, kHeight);19421943glClearColor(0.0f, 0.0f, 0.0f, 0.0f);1944glClear(GL_COLOR_BUFFER_BIT);19451946// Scale down without flipping.1947glBlitFramebuffer(0, 0, kWidth * 2, kHeight * 2, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,1948GL_NEAREST);19491950EXPECT_GL_NO_ERROR();19511952glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);19531954EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::red);1955EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::green);1956EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);1957EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::yellow);19581959glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);1960glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);19611962glClearColor(0.0f, 0.0f, 0.0f, 0.0f);1963glClear(GL_COLOR_BUFFER_BIT);19641965// Scale down and flip in the X direction.1966glBlitFramebuffer(0, 0, kWidth * 2, kHeight * 2, kWidth, 0, 0, kHeight, GL_COLOR_BUFFER_BIT,1967GL_NEAREST);19681969EXPECT_GL_NO_ERROR();19701971glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);19721973EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::blue);1974EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::yellow);1975EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::red);1976EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::green);1977}19781979// Blit stencil, with scissor and scale it.1980TEST_P(BlitFramebufferTest, BlitStencilScissoredScaled)1981{1982// http://anglebug.com/51061983ANGLE_SKIP_TEST_IF(IsMetal() && IsIntel() && IsOSX());19841985constexpr GLint kSize = 256;19861987// Create the destination framebuffer.1988GLTexture destColorbuf;1989glBindTexture(GL_TEXTURE_2D, destColorbuf.get());1990glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);19911992GLRenderbuffer destRenderbuf;1993glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf.get());1994glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kSize, kSize);19951996GLFramebuffer destFBO;1997glBindFramebuffer(GL_FRAMEBUFFER, destFBO.get());1998glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,1999destColorbuf.get(), 0);2000glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,2001destRenderbuf.get());20022003// Clear the destination buffer with gray and 0x10 stencil.2004GLColor gray(127, 127, 127, 255);2005glClearStencil(0x10);2006glClearColor(0.499f, 0.499f, 0.499f, 1.0f);2007glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);2008EXPECT_PIXEL_COLOR_EQ(0, 0, gray);2009EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);20102011// Create the source framebuffer.2012GLRenderbuffer renderbuf;2013glBindRenderbuffer(GL_RENDERBUFFER, renderbuf.get());2014glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kSize, kSize);20152016ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());2017ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());2018ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());20192020GLFramebuffer sourceFBO;2021glBindFramebuffer(GL_FRAMEBUFFER, sourceFBO.get());2022glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,2023renderbuf.get());20242025ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));20262027// Fill the stencil buffer with 0x1.2028glClearStencil(0x1);2029glClear(GL_STENCIL_BUFFER_BIT);20302031// Fill a smaller region of the buffer with 0x2.2032glEnable(GL_SCISSOR_TEST);2033glEnable(GL_STENCIL_TEST);2034glScissor(kSize / 4, kSize / 4, kSize / 2, kSize / 2);2035glStencilFunc(GL_ALWAYS, 0x2, 0xFF);2036glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);2037drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);20382039// Blit and scale down into the destination framebuffer (with scissor still enabled).2040//2041// Source looks like this:2042//2043// +----|----|----|----+2044// | |2045// | 0x1 |2046// - +---------+ -2047// | | | |2048// | | | |2049// - | 0x2 | -2050// | | | |2051// | | | |2052// - +---------+ -2053// | |2054// | |2055// +----|----|----|----+2056//2057// We want the destination to look like this:2058//2059// +----|----|----|----+2060// | |2061// | 0x10 |2062// - +---------+ -2063// | | 0x1 | |2064// | | +------+ |2065// - | | | -2066// | | | 0x2 | |2067// | | | | |2068// - +--+------+ -2069// | |2070// | |2071// +----|----|----|----+2072//2073// The corresponding blit would be: (0, 0, 3/4, 3/4) -> (1/4, 1/4, 3/4, 3/4). For testing, we2074// would like to avoid having the destination area and scissor to match. Using destination2075// area as (0, 0, 1, 1), and keeping the same scaling, the source area should be2076// (-3/8, -3/8, 9/8, 9/8).2077//2078glBindFramebuffer(GL_DRAW_FRAMEBUFFER, destFBO.get());2079constexpr GLint kBlitSrc[2] = {-3 * kSize / 8, 9 * kSize / 8};2080glBlitFramebuffer(kBlitSrc[0], kBlitSrc[0], kBlitSrc[1], kBlitSrc[1], 0, 0, kSize, kSize,2081GL_STENCIL_BUFFER_BIT, GL_NEAREST);20822083glBindFramebuffer(GL_FRAMEBUFFER, destFBO.get());20842085ASSERT_GL_NO_ERROR();20862087// Draw blue if the stencil is 0x1, which should be true only in the top and left of the inner2088// square.2089glDisable(GL_SCISSOR_TEST);2090glStencilMask(0);2091glStencilFunc(GL_EQUAL, 0x1, 0xFF);2092drawQuad(drawBlue.get(), essl3_shaders::PositionAttrib(), 0.5f);2093EXPECT_PIXEL_COLOR_EQ(0, 0, gray);2094EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);2095EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);2096EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);20972098EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::blue);2099EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::blue);2100EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::blue);21012102EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);2103EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, gray);21042105// Draw red if the stencil is 0x2, which should be true in the bottom/right of the middle2106// square after the blit.2107glStencilFunc(GL_EQUAL, 0x2, 0xFF);2108drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);2109EXPECT_PIXEL_COLOR_EQ(0, 0, gray);2110EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);2111EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);2112EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);21132114EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::blue);2115EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::blue);2116EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::blue);21172118EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);2119EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, GLColor::red);21202121// Draw green if the stencil is 0x10, which should be left untouched in the outer regions.2122glStencilFunc(GL_EQUAL, 0x10, 0xFF);2123drawQuad(drawGreen.get(), essl3_shaders::PositionAttrib(), 0.5f);2124EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);2125EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);2126EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);2127EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);21282129EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::blue);2130EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::blue);2131EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::blue);21322133EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);2134EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, GLColor::red);21352136ASSERT_GL_NO_ERROR();2137}21382139// Blit a subregion of an SRGB framebuffer to an RGB framebuffer.2140TEST_P(BlitFramebufferTest, PartialBlitSRGBToRGB)2141{2142constexpr const GLsizei kWidth = 256;2143constexpr const GLsizei kHeight = 256;21442145GLRenderbuffer sourceRBO, targetRBO;2146GLFramebuffer sourceFBO, targetFBO;2147initColorFBOWithCheckerPattern(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth * 2,2148kHeight * 2);2149initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);21502151EXPECT_GL_NO_ERROR();21522153glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);2154glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);21552156glViewport(0, 0, kWidth, kHeight);21572158glClearColor(0.0f, 0.0f, 0.0f, 0.0f);2159glClear(GL_COLOR_BUFFER_BIT);21602161// Blit a part of the source FBO without flipping.2162glBlitFramebuffer(kWidth, kHeight, kWidth * 2, kHeight * 2, 0, 0, kWidth, kHeight,2163GL_COLOR_BUFFER_BIT, GL_NEAREST);21642165EXPECT_GL_NO_ERROR();21662167glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);21682169EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::yellow);2170EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::yellow);2171EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::yellow);2172EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::yellow);21732174glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);2175glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);21762177glClearColor(0.0f, 0.0f, 0.0f, 0.0f);2178glClear(GL_COLOR_BUFFER_BIT);21792180// Blit a part of the source FBO and flip in the X direction.2181glBlitFramebuffer(kWidth * 2, 0, kWidth, kHeight, kWidth, 0, 0, kHeight, GL_COLOR_BUFFER_BIT,2182GL_NEAREST);21832184EXPECT_GL_NO_ERROR();21852186glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);21872188EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::blue);2189EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::blue);2190EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);2191EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::blue);2192}21932194// Blit an SRGB framebuffer with an oversized source area (parts outside the source area should be2195// clipped out).2196TEST_P(BlitFramebufferTest, BlitSRGBToRGBOversizedSourceArea)2197{2198constexpr const GLsizei kWidth = 256;2199constexpr const GLsizei kHeight = 256;22002201GLRenderbuffer sourceRBO, targetRBO;2202GLFramebuffer sourceFBO, targetFBO;2203initColorFBOWithCheckerPattern(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth, kHeight);2204initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);22052206EXPECT_GL_NO_ERROR();22072208glViewport(0, 0, kWidth, kHeight);22092210glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);2211glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);22122213glClearColor(0.0f, 0.0f, 1.0f, 1.0f);2214glClear(GL_COLOR_BUFFER_BIT);22152216// Blit so that the source area gets placed at the center of the target FBO.2217// The width of the source area is 1/4 of the width of the target FBO.2218glBlitFramebuffer(-3 * kWidth / 2, -3 * kHeight / 2, 5 * kWidth / 2, 5 * kHeight / 2, 0, 0,2219kWidth, kHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);22202221EXPECT_GL_NO_ERROR();22222223glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);22242225// Source FBO colors can be found in the middle of the target FBO.2226EXPECT_PIXEL_COLOR_EQ(7 * kWidth / 16, 7 * kHeight / 16, GLColor::red);2227EXPECT_PIXEL_COLOR_EQ(7 * kWidth / 16, 9 * kHeight / 16, GLColor::green);2228EXPECT_PIXEL_COLOR_EQ(9 * kWidth / 16, 7 * kHeight / 16, GLColor::blue);2229EXPECT_PIXEL_COLOR_EQ(9 * kWidth / 16, 9 * kHeight / 16, GLColor::yellow);22302231// Clear color should remain around the edges of the target FBO (WebGL 2.0 spec explicitly2232// requires this and ANGLE is expected to follow that).2233EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::blue);2234EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::blue);2235EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);2236EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::blue);2237}22382239// Blit an SRGB framebuffer with an oversized dest area (even though the result is clipped, it2240// should be scaled as if the whole dest area was used).2241TEST_P(BlitFramebufferTest, BlitSRGBToRGBOversizedDestArea)2242{2243constexpr const GLsizei kWidth = 256;2244constexpr const GLsizei kHeight = 256;22452246GLRenderbuffer sourceRBO, targetRBO;2247GLFramebuffer sourceFBO, targetFBO;2248initColorFBOWithCheckerPattern(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth, kHeight);2249initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);22502251EXPECT_GL_NO_ERROR();22522253glViewport(0, 0, kWidth, kHeight);22542255glClearColor(0.0f, 0.0f, 1.0f, 1.0f);2256glClear(GL_COLOR_BUFFER_BIT);22572258// Dest is oversized but centered the same as source2259glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);2260glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);22612262glBlitFramebuffer(0, 0, kWidth, kHeight, -kWidth / 2, -kHeight / 2, 3 * kWidth / 2,22633 * kHeight / 2, GL_COLOR_BUFFER_BIT, GL_NEAREST);22642265EXPECT_GL_NO_ERROR();22662267glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);22682269// Expected result:2270//2271// +-------+-------+2272// | | |2273// | R | B |2274// | | |2275// +-------+-------+2276// | | |2277// | G | Y |2278// | | |2279// +-------+-------+2280//2281EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);2282EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::red);2283EXPECT_PIXEL_COLOR_EQ(kWidth / 2 - 1, kHeight / 2 - 1, GLColor::red);22842285EXPECT_PIXEL_COLOR_EQ(1, kWidth - 1, GLColor::green);2286EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::green);2287EXPECT_PIXEL_COLOR_EQ(kWidth / 2 - 1, kHeight / 2 + 1, GLColor::green);22882289EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 1, GLColor::blue);2290EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);2291EXPECT_PIXEL_COLOR_EQ(kWidth / 2 + 1, kHeight / 2 - 1, GLColor::blue);22922293EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::yellow);2294EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::yellow);2295EXPECT_PIXEL_COLOR_EQ(kWidth / 2 + 1, kHeight / 2 + 1, GLColor::yellow);22962297// Dest is oversized in the negative direction2298glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);2299glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);23002301glBlitFramebuffer(0, 0, kWidth, kHeight, -kWidth / 2, -kHeight / 2, kWidth, kHeight,2302GL_COLOR_BUFFER_BIT, GL_NEAREST);23032304EXPECT_GL_NO_ERROR();23052306glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);23072308// Expected result:2309//2310// Width / 42311// |2312// V2313// +---+-----------+2314// | R | B |2315// +---+-----------+ <- Height / 42316// | | |2317// | | |2318// | G | Y |2319// | | |2320// | | |2321// +---+-----------+2322//2323EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);2324EXPECT_PIXEL_COLOR_EQ(0, kHeight / 4 - 1, GLColor::red);2325EXPECT_PIXEL_COLOR_EQ(kWidth / 4 - 1, 0, GLColor::red);2326EXPECT_PIXEL_COLOR_EQ(kWidth / 4 - 1, kHeight / 4 - 1, GLColor::red);2327EXPECT_PIXEL_COLOR_EQ(kWidth / 8, kHeight / 8, GLColor::red);23282329EXPECT_PIXEL_COLOR_EQ(0, kHeight / 4 + 1, GLColor::green);2330EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::green);2331EXPECT_PIXEL_COLOR_EQ(kWidth / 4 - 1, kHeight / 4 + 1, GLColor::green);2332EXPECT_PIXEL_COLOR_EQ(kWidth / 4 - 1, kHeight - 1, GLColor::green);2333EXPECT_PIXEL_COLOR_EQ(kWidth / 8, kHeight / 2, GLColor::green);23342335EXPECT_PIXEL_COLOR_EQ(kWidth / 4 + 1, 0, GLColor::blue);2336EXPECT_PIXEL_COLOR_EQ(kWidth / 4 + 1, kHeight / 4 - 1, GLColor::blue);2337EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::blue);2338EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight / 4 - 1, GLColor::blue);2339EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 8, GLColor::blue);23402341EXPECT_PIXEL_COLOR_EQ(kWidth / 4 + 1, kHeight / 4 + 1, GLColor::yellow);2342EXPECT_PIXEL_COLOR_EQ(kWidth / 4 + 1, kHeight - 1, GLColor::yellow);2343EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight / 4 + 1, GLColor::yellow);2344EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::yellow);2345EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::yellow);23462347// Dest is oversized in the positive direction2348glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);2349glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);23502351glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, 3 * kWidth / 2, 3 * kHeight / 2,2352GL_COLOR_BUFFER_BIT, GL_NEAREST);23532354EXPECT_GL_NO_ERROR();23552356glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);23572358// Expected result:2359//2360// 3 * Width / 42361// |2362// V2363// +-----------+---+2364// | | |2365// | | |2366// | R | B |2367// | | |2368// | | |2369// +-----------+---+ <- 3 * Height / 42370// | G | Y |2371// +-----------+---+2372//2373EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);2374EXPECT_PIXEL_COLOR_EQ(0, 3 * kHeight / 4 - 1, GLColor::red);2375EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 - 1, 0, GLColor::red);2376EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 - 1, 3 * kHeight / 4 - 1, GLColor::red);2377EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::red);23782379EXPECT_PIXEL_COLOR_EQ(0, 3 * kHeight / 4 + 1, GLColor::green);2380EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::green);2381EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 - 1, 3 * kHeight / 4 + 1, GLColor::green);2382EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 - 1, kHeight - 1, GLColor::green);2383EXPECT_PIXEL_COLOR_EQ(kWidth / 2, 7 * kHeight / 8, GLColor::green);23842385EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 + 1, 0, GLColor::blue);2386EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 + 1, 3 * kHeight / 4 - 1, GLColor::blue);2387EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::blue);2388EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 3 * kHeight / 4 - 1, GLColor::blue);2389EXPECT_PIXEL_COLOR_EQ(7 * kWidth / 8, kHeight / 2, GLColor::blue);23902391EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 + 1, 3 * kHeight / 4 + 1, GLColor::yellow);2392EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 + 1, kHeight - 1, GLColor::yellow);2393EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 3 * kHeight / 4 + 1, GLColor::yellow);2394EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::yellow);2395EXPECT_PIXEL_COLOR_EQ(7 * kWidth / 8, 7 * kHeight / 8, GLColor::yellow);2396}23972398// Test blitFramebuffer size overflow checks. WebGL 2.0 spec section 5.41. We do validation for2399// overflows also in non-WebGL mode to avoid triggering driver bugs.2400TEST_P(BlitFramebufferTest, BlitFramebufferSizeOverflow)2401{2402GLTexture textures[2];2403glBindTexture(GL_TEXTURE_2D, textures[0]);2404glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 4, 4);2405glBindTexture(GL_TEXTURE_2D, textures[1]);2406glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 4, 4);24072408GLFramebuffer framebuffers[2];2409glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffers[0]);2410glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffers[1]);24112412ASSERT_GL_NO_ERROR();24132414glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0],24150);2416glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1],24170);2418ASSERT_GL_NO_ERROR();24192420// srcX2421glBlitFramebuffer(-1, 0, std::numeric_limits<GLint>::max(), 4, 0, 0, 4, 4, GL_COLOR_BUFFER_BIT,2422GL_NEAREST);2423EXPECT_GL_ERROR(GL_INVALID_VALUE);2424glBlitFramebuffer(std::numeric_limits<GLint>::max(), 0, -1, 4, 0, 0, 4, 4, GL_COLOR_BUFFER_BIT,2425GL_NEAREST);2426EXPECT_GL_ERROR(GL_INVALID_VALUE);24272428// srcY2429glBlitFramebuffer(0, -1, 4, std::numeric_limits<GLint>::max(), 0, 0, 4, 4, GL_COLOR_BUFFER_BIT,2430GL_NEAREST);2431EXPECT_GL_ERROR(GL_INVALID_VALUE);2432glBlitFramebuffer(0, std::numeric_limits<GLint>::max(), 4, -1, 0, 0, 4, 4, GL_COLOR_BUFFER_BIT,2433GL_NEAREST);2434EXPECT_GL_ERROR(GL_INVALID_VALUE);24352436// dstX2437glBlitFramebuffer(0, 0, 4, 4, -1, 0, std::numeric_limits<GLint>::max(), 4, GL_COLOR_BUFFER_BIT,2438GL_NEAREST);2439EXPECT_GL_ERROR(GL_INVALID_VALUE);2440glBlitFramebuffer(0, 0, 4, 4, std::numeric_limits<GLint>::max(), 0, -1, 4, GL_COLOR_BUFFER_BIT,2441GL_NEAREST);2442EXPECT_GL_ERROR(GL_INVALID_VALUE);24432444// dstY2445glBlitFramebuffer(0, 0, 4, 4, 0, -1, 4, std::numeric_limits<GLint>::max(), GL_COLOR_BUFFER_BIT,2446GL_NEAREST);2447EXPECT_GL_ERROR(GL_INVALID_VALUE);2448glBlitFramebuffer(0, 0, 4, 4, 0, std::numeric_limits<GLint>::max(), 4, -1, GL_COLOR_BUFFER_BIT,2449GL_NEAREST);2450EXPECT_GL_ERROR(GL_INVALID_VALUE);2451}24522453// Test blitFramebuffer size overflow checks. WebGL 2.0 spec section 5.41. Similar to above test,2454// but this test more accurately duplicates the behavior of the WebGL test2455// conformance2/rendering/blitframebuffer-size-overflow.html, which covers a few more edge cases.2456TEST_P(BlitFramebufferTest, BlitFramebufferSizeOverflow2)2457{2458GLTexture textures[2];2459glBindTexture(GL_TEXTURE_2D, textures[0]);2460glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 4, 4);2461glBindTexture(GL_TEXTURE_2D, textures[1]);2462glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 4, 4);24632464GLFramebuffer framebuffers[2];2465glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffers[0]);2466glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffers[1]);24672468ASSERT_GL_NO_ERROR();24692470glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0],24710);2472glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1],24730);2474ASSERT_GL_NO_ERROR();24752476GLint width = 8;2477GLint height = 8;24782479GLTexture tex0;2480glBindTexture(GL_TEXTURE_2D, tex0);2481glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);24822483GLFramebuffer fb0;2484glBindFramebuffer(GL_READ_FRAMEBUFFER, fb0);2485glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex0, 0);24862487GLTexture tex1;2488glBindTexture(GL_TEXTURE_2D, tex1);2489glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);24902491GLFramebuffer fb1;2492glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb1);2493glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex1, 0);24942495GLint max = std::numeric_limits<GLint>::max();2496// Using max 32-bit integer as blitFramebuffer parameter should succeed.2497glBlitFramebuffer(0, 0, max, max, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);2498glBlitFramebuffer(0, 0, width, height, 0, 0, max, max, GL_COLOR_BUFFER_BIT, GL_NEAREST);2499glBlitFramebuffer(0, 0, max, max, 0, 0, max, max, GL_COLOR_BUFFER_BIT, GL_NEAREST);2500EXPECT_GL_NO_ERROR();25012502// Using blitFramebuffer parameters where calculated width/height matches max 32-bit integer2503// should succeed2504glBlitFramebuffer(-1, -1, max - 1, max - 1, 0, 0, width, height, GL_COLOR_BUFFER_BIT,2505GL_NEAREST);2506glBlitFramebuffer(0, 0, width, height, -1, -1, max - 1, max - 1, GL_COLOR_BUFFER_BIT,2507GL_NEAREST);2508glBlitFramebuffer(-1, -1, max - 1, max - 1, -1, -1, max - 1, max - 1, GL_COLOR_BUFFER_BIT,2509GL_NEAREST);2510EXPECT_GL_NO_ERROR();25112512// Using source width/height greater than max 32-bit integer should fail.2513glBlitFramebuffer(-1, -1, max, max, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);2514EXPECT_GL_ERROR(GL_INVALID_VALUE);25152516// Using source width/height greater than max 32-bit integer should fail.2517glBlitFramebuffer(max, max, -1, -1, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);2518EXPECT_GL_ERROR(GL_INVALID_VALUE);25192520// Using destination width/height greater than max 32-bit integer should fail.2521glBlitFramebuffer(0, 0, width, height, -1, -1, max, max, GL_COLOR_BUFFER_BIT, GL_NEAREST);2522EXPECT_GL_ERROR(GL_INVALID_VALUE);25232524// Using destination width/height greater than max 32-bit integer should fail.2525glBlitFramebuffer(0, 0, width, height, max, max, -1, -1, GL_COLOR_BUFFER_BIT, GL_NEAREST);2526EXPECT_GL_ERROR(GL_INVALID_VALUE);25272528// Using both source and destination width/height greater than max 32-bit integer should fail.2529glBlitFramebuffer(-1, -1, max, max, -1, -1, max, max, GL_COLOR_BUFFER_BIT, GL_NEAREST);2530EXPECT_GL_ERROR(GL_INVALID_VALUE);25312532// Using minimum and maximum integers for all boundaries should fail.2533glBlitFramebuffer(-max - 1, -max - 1, max, max, -max - 1, -max - 1, max, max,2534GL_COLOR_BUFFER_BIT, GL_NEAREST);2535EXPECT_GL_ERROR(GL_INVALID_VALUE);2536}25372538// Test an edge case in D3D11 stencil blitting on the CPU that does not properly clip the2539// destination regions2540TEST_P(BlitFramebufferTest, BlitFramebufferStencilClipNoIntersection)2541{2542GLFramebuffer framebuffers[2];2543glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffers[0]);2544glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffers[1]);25452546GLRenderbuffer renderbuffers[2];2547glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[0]);2548glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 4, 4);2549glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,2550renderbuffers[0]);25512552glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[1]);2553glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 4, 4);2554glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,2555renderbuffers[1]);25562557glBlitFramebuffer(0, 0, 4, 4, 1 << 24, 1 << 24, 1 << 25, 1 << 25, GL_STENCIL_BUFFER_BIT,2558GL_NEAREST);2559EXPECT_GL_NO_ERROR();2560}25612562// Covers an edge case with blitting borderline values.2563TEST_P(BlitFramebufferTest, OOBWrite)2564{2565constexpr size_t length = 0x100000;2566GLFramebuffer rfb;2567GLFramebuffer dfb;2568GLRenderbuffer rb1;2569GLRenderbuffer rb2;2570glBindFramebuffer(GL_READ_FRAMEBUFFER, rfb);2571glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dfb);2572glBindRenderbuffer(GL_RENDERBUFFER, rb1);2573glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 0x1000, 2);2574glBindRenderbuffer(GL_RENDERBUFFER, rb2);2575glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 2, 2);2576glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,2577rb1);2578glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,2579rb2);2580glBlitFramebuffer(1, 0, 0, 1, 1, 0, (2147483648 / 2) - (length / 4) + 1, 1,2581GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);2582ASSERT_GL_NO_ERROR();2583}25842585// Test blitting a depthStencil buffer with multiple depth values to a larger size.2586TEST_P(BlitFramebufferTest, BlitDepthStencilPixelByPixel)2587{2588ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());25892590glViewport(0, 0, 128, 1);2591glEnable(GL_DEPTH_TEST);25922593GLFramebuffer srcFramebuffer;2594GLRenderbuffer srcRenderbuffer;2595glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);2596glBindRenderbuffer(GL_RENDERBUFFER, srcRenderbuffer);2597glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 128, 1);2598glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,2599srcRenderbuffer);2600glClearDepthf(1.0f);2601glClear(GL_DEPTH_BUFFER_BIT);26022603drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.0f, 0.5f);2604glViewport(0, 0, 256, 2);26052606GLFramebuffer dstFramebuffer;2607GLRenderbuffer dstRenderbuffer;2608glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFramebuffer);2609glBindRenderbuffer(GL_RENDERBUFFER, dstRenderbuffer);2610glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 256, 2);2611glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,2612dstRenderbuffer);26132614GLTexture dstColor;2615glBindTexture(GL_TEXTURE_2D, dstColor);2616glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 2);2617glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstColor, 0);26182619glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);2620glBlitFramebuffer(0, 0, 128, 1, 0, 0, 256, 2, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,2621GL_NEAREST);26222623glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);2624glClearColor(0.0f, 1.0f, 0.0f, 1.0f);2625glClear(GL_COLOR_BUFFER_BIT);2626glDepthMask(false);2627glDepthFunc(GL_LESS);2628drawQuad(drawRed, essl1_shaders::PositionAttrib(), -0.01f, 0.5f);2629EXPECT_PIXEL_RECT_EQ(64, 0, 128, 1, GLColor::red);26302631ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());2632glEnable(GL_DEPTH_TEST);2633glDepthMask(false);2634glDepthFunc(GL_GREATER);2635drawQuad(drawBlue, essl1_shaders::PositionAttrib(), 0.01f, 0.5f);2636EXPECT_PIXEL_RECT_EQ(64, 0, 128, 1, GLColor::blue);2637}26382639// Test that a draw call to a small FBO followed by a resolve of a large FBO works.2640TEST_P(BlitFramebufferTestES31, DrawToSmallFBOThenResolveLargeFBO)2641{2642GLFramebuffer fboMS[2];2643GLTexture textureMS[2];2644GLFramebuffer fboSS;2645GLTexture textureSS;26462647// A bug in the Vulkan backend grew the render area of the previous render pass on blit, even2648// though the previous render pass belonged to an unrelated framebuffer. This test only needs2649// to make sure that the FBO being resolved is not strictly smaller than the previous FBO which2650// was drawn to.2651constexpr GLsizei kLargeWidth = 127;2652constexpr GLsizei kLargeHeight = 54;2653constexpr GLsizei kSmallWidth = 37;2654constexpr GLsizei kSmallHeight = 79;26552656ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());26572658// Create resolve target.2659glBindTexture(GL_TEXTURE_2D, textureSS);2660glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kLargeWidth, kLargeHeight);26612662glBindFramebuffer(GL_FRAMEBUFFER, fboSS);2663glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureSS, 0);2664ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);26652666// Create multisampled framebuffers and draw into them one by one.2667for (size_t fboIndex = 0; fboIndex < 2; ++fboIndex)2668{2669const GLsizei width = fboIndex == 0 ? kLargeWidth : kSmallWidth;2670const GLsizei height = fboIndex == 0 ? kLargeHeight : kSmallHeight;26712672glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureMS[fboIndex]);2673glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, width, height, GL_TRUE);26742675glBindFramebuffer(GL_FRAMEBUFFER, fboMS[fboIndex]);2676glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,2677textureMS[fboIndex], 0);2678ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);26792680glViewport(0, 0, width, height);2681drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.8f);2682EXPECT_GL_NO_ERROR();2683}26842685// Resolve the first FBO2686glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboSS);2687glBindFramebuffer(GL_READ_FRAMEBUFFER, fboMS[0]);26882689glViewport(0, 0, kLargeWidth, kLargeHeight);2690glBlitFramebuffer(0, 0, kLargeWidth, kLargeHeight, 0, 0, kLargeWidth, kLargeHeight,2691GL_COLOR_BUFFER_BIT, GL_NEAREST);2692EXPECT_GL_NO_ERROR();26932694// Verify the resolve2695glBindFramebuffer(GL_READ_FRAMEBUFFER, fboSS);2696EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);2697EXPECT_PIXEL_COLOR_EQ(kLargeWidth - 1, kLargeHeight - 1, GLColor::red);2698}26992700// Use this to select which configurations (e.g. which renderer, which GLES major version) these2701// tests should be run against.2702GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BlitFramebufferANGLETest);2703ANGLE_INSTANTIATE_TEST(BlitFramebufferANGLETest,2704ES2_D3D9(),2705ES2_D3D11(),2706ES2_D3D11_PRESENT_PATH_FAST(),2707ES2_OPENGL(),2708ES3_OPENGL(),2709ES2_VULKAN(),2710ES3_VULKAN(),2711WithEmulatedPrerotation(ES3_VULKAN(), 90),2712WithEmulatedPrerotation(ES3_VULKAN(), 180),2713WithEmulatedPrerotation(ES3_VULKAN(), 270),2714ES2_METAL(),2715WithNoShaderStencilOutput(ES2_METAL()));27162717GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BlitFramebufferTest);2718ANGLE_INSTANTIATE_TEST_ES3_AND(BlitFramebufferTest, WithNoShaderStencilOutput(ES3_METAL()));27192720GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BlitFramebufferTestES31);2721ANGLE_INSTANTIATE_TEST_ES31(BlitFramebufferTestES31);2722} // namespace272327242725