src/third_party/angle/src/tests/gl_tests/MultisampledRenderToTextureTest.cpp
// Draw, copy, then blend.  The copy will make sure an implicit resolve happens.  Regardless, the
// following draw should retain the data written by the first draw command.
// Uses color attachments 0 and 1.  Attachment 0 is a normal multisampled texture, while attachment
// 1 is a multisampled-render-to-texture texture.
Draw, copy, then blend.  The copy will make sure an implicit resolve happens.  Regardless, the
following draw should retain the data written by the first draw command.
Uses color attachments 0 and 1.  Attachment 0 is a normal multisampled texture, while attachment
1 is a multisampled-render-to-texture texture.
Draw copy then blend . The copy will make sure an implicit resolve happens . Regardless the following draw should retain the data written by the first draw command . Uses color attachments 0 and 1 . Attachment 0 is a normal multisampled texture while attachment 1 is a multisampled - render - to - texture texture .
TEST_P(MultisampledRenderToTextureES31Test, MixedMultisampledAndMultisampledRenderToTexture)
{
    ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
    ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture2"));
    constexpr GLsizei kSize = 64;
    setupCopyTexProgram();
    GLTexture colorMS0;
    glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, colorMS0);
    glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, true);
    GLTexture colorMS1;
    glBindTexture(GL_TEXTURE_2D, colorMS1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    GLFramebuffer fboMS;
    glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
                           colorMS0, 0);
    glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D,
                                         colorMS1, 0, 4);
    ASSERT_GL_NO_ERROR();
    constexpr bool kBuffersEnabled[8] = {true, true};
    GLuint drawColor;
    setupUniformColorProgramMultiRenderTarget(kBuffersEnabled, &drawColor);
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);
    constexpr GLenum kDrawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
    glDrawBuffers(2, kDrawBuffers);
    glReadBuffer(GL_COLOR_ATTACHMENT1);
    ASSERT_GL_NO_ERROR();
    glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    ASSERT_GL_NO_ERROR();
    glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 0.5f);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    const GLColor kExpected(127, 127, 0, 191);
    EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
    EXPECT_PIXEL_COLOR_NEAR(kSize - 1, 0, kExpected, 1);
    EXPECT_PIXEL_COLOR_NEAR(0, kSize - 1, kExpected, 1);
    EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected, 1);
    verifyResults(texture, GLColor::red, kSize, 0, 0, kSize, kSize);
    ASSERT_GL_NO_ERROR();
    glDeleteProgram(drawColor);
}
TEST_P ( MultisampledRenderToTextureES31Test , MixedMultisampledAndMultisampledRenderToTexture ) { ANGLE_SKIP_TEST_IF ( ! EnsureGLExtensionEnabled ( " " ) ) ; ANGLE_SKIP_TEST_IF ( ! EnsureGLExtensionEnabled ( " " ) ) ; constexpr GLsizei kSize = 64 ; setupCopyTexProgram ( ) ; GLTexture colorMS0 ; glBindTexture ( GL_TEXTURE_2D_MULTISAMPLE , colorMS0 ) ; glTexStorage2DMultisample ( GL_TEXTURE_2D_MULTISAMPLE , 4 , GL_RGBA8 , kSize , kSize , true ) ; GLTexture colorMS1 ; glBindTexture ( GL_TEXTURE_2D , colorMS1 ) ; glTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA , kSize , kSize , 0 , GL_RGBA , GL_UNSIGNED_BYTE , nullptr ) ; GLFramebuffer fboMS ; glBindFramebuffer ( GL_FRAMEBUFFER , fboMS ) ; glFramebufferTexture2D ( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT0 , GL_TEXTURE_2D_MULTISAMPLE , colorMS0 , 0 ) ; glFramebufferTexture2DMultisampleEXT ( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT1 , GL_TEXTURE_2D , colorMS1 , 0 , 4 ) ; ASSERT_GL_NO_ERROR ( ) ; constexpr bool kBuffersEnabled [ 8 ] = { true , true } ; GLuint drawColor ; setupUniformColorProgramMultiRenderTarget ( kBuffersEnabled , & drawColor ) ; glUseProgram ( drawColor ) ; GLint colorUniformLocation = glGetUniformLocation ( drawColor , angle :: essl1_shaders :: ColorUniform ( ) ) ; ASSERT_NE ( colorUniformLocation , -1 ) ; constexpr GLenum kDrawBuffers [ ] = { GL_COLOR_ATTACHMENT0 , GL_COLOR_ATTACHMENT1 } ; glDrawBuffers ( 2 , kDrawBuffers ) ; glReadBuffer ( GL_COLOR_ATTACHMENT1 ) ; ASSERT_GL_NO_ERROR ( ) ; glUniform4f ( colorUniformLocation , 1.0f , 0.0f , 0.0f , 1.0f ) ; drawQuad ( drawColor , essl1_shaders :: PositionAttrib ( ) , 0.5f ) ; ASSERT_GL_NO_ERROR ( ) ; GLTexture texture ; glBindTexture ( GL_TEXTURE_2D , texture ) ; glCopyTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA , 0 , 0 , kSize , kSize , 0 ) ; glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST ) ; glTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST ) ; ASSERT_GL_NO_ERROR ( ) ; glUniform4f ( colorUniformLocation , 0.0f , 1.0f , 0.0f , 0.5f ) ; glEnable ( GL_BLEND ) ; glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ; drawQuad ( drawColor , essl1_shaders :: PositionAttrib ( ) , 0.5f ) ; ASSERT_GL_NO_ERROR ( ) ; const GLColor kExpected ( 127 , 127 , 0 , 191 ) ; EXPECT_PIXEL_COLOR_NEAR ( 0 , 0 , kExpected , 1 ) ; EXPECT_PIXEL_COLOR_NEAR ( kSize - 1 , 0 , kExpected , 1 ) ; EXPECT_PIXEL_COLOR_NEAR ( 0 , kSize - 1 , kExpected , 1 ) ; EXPECT_PIXEL_COLOR_NEAR ( kSize - 1 , kSize - 1 , kExpected , 1 ) ; verifyResults ( texture , GLColor :: red , kSize , 0 , 0 , kSize , kSize ) ; ASSERT_GL_NO_ERROR ( ) ; glDeleteProgram ( drawColor ) ; }
Draw, copy, then blend.
Draw copy then blend .
// Create multisampled framebuffer to draw into, use color attachment 1 // Setup program to render into attachments 0 and 1. // Draw red into the multisampled color buffers. // Create a texture and copy from one of them. // Blend half-transparent green into the multisampled color buffers. // Verify that the textures are now yellow // For completeness, verify that the texture used as copy target is red.