src/third_party/angle/src/tests/gl_tests/MultisampledRenderToTextureTest.cpp
// Draw, copy, redefine the color attachment with a different format, clear, copy then draw.  The
// initial draw will need to unresolve color as the color attachment is preinitilized with data.
// Redefining the color attachment forces framebuffer to recreate when the clear is called.  The
// second copy resolves the clear and the final draw unresolves again.  In the Vulkan backend,
// mismatches in unresolve state between framebuffer and render pass will result in an ASSERT and a
// validation error (if ASSERT is removed).
Draw, copy, redefine the color attachment with a different format, clear, copy then draw.  The
initial draw will need to unresolve color as the color attachment is preinitilized with data.
Redefining the color attachment forces framebuffer to recreate when the clear is called.  The
second copy resolves the clear and the final draw unresolves again.  In the Vulkan backend,
mismatches in unresolve state between framebuffer and render pass will result in an ASSERT and a
validation error (if ASSERT is removed).
Draw copy redefine the color attachment with a different format clear copy then draw . The initial draw will need to unresolve color as the color attachment is preinitilized with data . Redefining the color attachment forces framebuffer to recreate when the clear is called . The second copy resolves the clear and the final draw unresolves again . In the Vulkan backend mismatches in unresolve state between framebuffer and render pass will result in an ASSERT and a validation error ( if ASSERT is removed ) .
TEST_P(MultisampledRenderToTextureES3Test, DrawCopyRedefineClearCopyThenDraw)
{
    ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
    constexpr GLsizei kSize = 64;
    setupCopyTexProgram();
    GLFramebuffer fboMS;
    glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
    std::vector<GLColor> initialColorData(kSize * kSize, GLColor::black);
    GLTexture colorMS;
    glBindTexture(GL_TEXTURE_2D, colorMS);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 initialColorData.data());
    glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                         colorMS, 0, 4);
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
    glUseProgram(drawColor);
    GLint colorUniformLocation =
        glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
    ASSERT_NE(colorUniformLocation, -1);
    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);
    glBindTexture(GL_TEXTURE_2D, colorMS);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, kSize, kSize, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
    ASSERT_GL_NO_ERROR();
    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    GLTexture texture2;
    glBindTexture(GL_TEXTURE_2D, texture2);
    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, kSize, kSize, 0);
    glUseProgram(drawColor);
    glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE);
    drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
    ASSERT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::cyan);
    EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::cyan);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::cyan);
    ASSERT_GL_NO_ERROR();
    verifyResults(texture, GLColor::red, kSize, 0, 0, kSize, kSize);
    ASSERT_GL_NO_ERROR();
}
TEST_P ( MultisampledRenderToTextureES3Test , DrawCopyRedefineClearCopyThenDraw ) { ANGLE_SKIP_TEST_IF ( ! EnsureGLExtensionEnabled ( " " ) ) ; constexpr GLsizei kSize = 64 ; setupCopyTexProgram ( ) ; GLFramebuffer fboMS ; glBindFramebuffer ( GL_FRAMEBUFFER , fboMS ) ; std :: vector < GLColor > initialColorData ( kSize * kSize , GLColor :: black ) ; GLTexture colorMS ; glBindTexture ( GL_TEXTURE_2D , colorMS ) ; glTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA , kSize , kSize , 0 , GL_RGBA , GL_UNSIGNED_BYTE , initialColorData . data ( ) ) ; glFramebufferTexture2DMultisampleEXT ( GL_FRAMEBUFFER , GL_COLOR_ATTACHMENT0 , GL_TEXTURE_2D , colorMS , 0 , 4 ) ; EXPECT_GL_FRAMEBUFFER_COMPLETE ( GL_FRAMEBUFFER ) ; ANGLE_GL_PROGRAM ( drawColor , essl1_shaders :: vs :: Simple ( ) , essl1_shaders :: fs :: UniformColor ( ) ) ; glUseProgram ( drawColor ) ; GLint colorUniformLocation = glGetUniformLocation ( drawColor , angle :: essl1_shaders :: ColorUniform ( ) ) ; ASSERT_NE ( colorUniformLocation , -1 ) ; 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 ) ; glBindTexture ( GL_TEXTURE_2D , colorMS ) ; glTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGB , kSize , kSize , 0 , GL_RGB , GL_UNSIGNED_BYTE , nullptr ) ; ASSERT_GL_NO_ERROR ( ) ; EXPECT_GL_FRAMEBUFFER_COMPLETE ( GL_FRAMEBUFFER ) ; glClearColor ( 0.0f , 1.0f , 0.0f , 1.0f ) ; glClear ( GL_COLOR_BUFFER_BIT ) ; GLTexture texture2 ; glBindTexture ( GL_TEXTURE_2D , texture2 ) ; glCopyTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGB , 0 , 0 , kSize , kSize , 0 ) ; glUseProgram ( drawColor ) ; glUniform4f ( colorUniformLocation , 0.0f , 0.0f , 1.0f , 1.0f ) ; glEnable ( GL_BLEND ) ; glBlendFunc ( GL_ONE , GL_ONE ) ; drawQuad ( drawColor , essl1_shaders :: PositionAttrib ( ) , 0.5f ) ; ASSERT_GL_NO_ERROR ( ) ; EXPECT_PIXEL_COLOR_EQ ( 0 , 0 , GLColor :: cyan ) ; EXPECT_PIXEL_COLOR_EQ ( kSize - 1 , 0 , GLColor :: cyan ) ; EXPECT_PIXEL_COLOR_EQ ( 0 , kSize - 1 , GLColor :: cyan ) ; EXPECT_PIXEL_COLOR_EQ ( kSize - 1 , kSize - 1 , GLColor :: cyan ) ; ASSERT_GL_NO_ERROR ( ) ; verifyResults ( texture , GLColor :: red , kSize , 0 , 0 , kSize , kSize ) ; ASSERT_GL_NO_ERROR ( ) ; }
Draw, copy, redefine the color attachment with a different format, clear, copy then draw.
Draw copy redefine the color attachment with a different format clear copy then draw .
// Create multisampled framebuffer to draw into // Draw red into the multisampled color buffer. // Draw into framebuffer.  This will unresolve color. // Create a texture and copy into it. // Incompatibly redefine the texture, forcing its image to be recreated. // Create another texture and copy into it. // Clear to green and blend blue into the multisampled color buffer. // Verify that the texture is now cyan // For completeness, verify that the texture used as copy target is red.