src/third_party/angle/src/tests/gl_tests/BlitFramebufferANGLETest.cpp
// Blit stencil, with scissor and scale it.
Blit stencil, with scissor and scale it.
Blit stencil with scissor and scale it .
TEST_P(BlitFramebufferTest, BlitStencilScissoredScaled)
{
    ANGLE_SKIP_TEST_IF(IsMetal() && IsIntel() && IsOSX());
    constexpr GLint kSize = 256;
    GLTexture destColorbuf;
    glBindTexture(GL_TEXTURE_2D, destColorbuf.get());
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
    GLRenderbuffer destRenderbuf;
    glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf.get());
    glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kSize, kSize);
    GLFramebuffer destFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, destFBO.get());
    glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                           destColorbuf.get(), 0);
    glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                              destRenderbuf.get());
    GLColor gray(127, 127, 127, 255);
    glClearStencil(0x10);
    glClearColor(0.499f, 0.499f, 0.499f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
    EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);
    GLRenderbuffer renderbuf;
    glBindRenderbuffer(GL_RENDERBUFFER, renderbuf.get());
    glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kSize, kSize);
    ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
    ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
    ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
    GLFramebuffer sourceFBO;
    glBindFramebuffer(GL_FRAMEBUFFER, sourceFBO.get());
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
                              renderbuf.get());
    ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
    glClearStencil(0x1);
    glClear(GL_STENCIL_BUFFER_BIT);
    glEnable(GL_SCISSOR_TEST);
    glEnable(GL_STENCIL_TEST);
    glScissor(kSize / 4, kSize / 4, kSize / 2, kSize / 2);
    glStencilFunc(GL_ALWAYS, 0x2, 0xFF);
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
    drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);
     Source looks like this:
         +----|----|----|----+
         |                   |
         |       0x1         |
         -    +---------+    -
         |    |         |    |
         |    |         |    |
         -    |   0x2   |    -
         |    |         |    |
         |    |         |    |
         -    +---------+    -
         |                   |
         |                   |
         +----|----|----|----+
     We want the destination to look like this:
         +----|----|----|----+
         |                   |
         |       0x10        |
         -    +---------+    -
         |    |  0x1    |    |
         |    |  +------+    |
         -    |  |      |    -
         |    |  | 0x2  |    |
         |    |  |      |    |
         -    +--+------+    -
         |                   |
         |                   |
         +----|----|----|----+
     The corresponding blit would be: (0, 0, 3/4, 3/4) -> (1/4, 1/4, 3/4, 3/4).  For testing, we
     would like to avoid having the destination area and scissor to match.  Using destination
     area as (0, 0, 1, 1), and keeping the same scaling, the source area should be
     (-3/8, -3/8, 9/8, 9/8).
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, destFBO.get());
    constexpr GLint kBlitSrc[2] = {-3 * kSize / 8, 9 * kSize / 8};
    glBlitFramebuffer(kBlitSrc[0], kBlitSrc[0], kBlitSrc[1], kBlitSrc[1], 0, 0, kSize, kSize,
                      GL_STENCIL_BUFFER_BIT, GL_NEAREST);
    glBindFramebuffer(GL_FRAMEBUFFER, destFBO.get());
    ASSERT_GL_NO_ERROR();
     Draw blue if the stencil is 0x1, which should be true only in the top and left of the inner
     square.
    glDisable(GL_SCISSOR_TEST);
    glStencilMask(0);
    glStencilFunc(GL_EQUAL, 0x1, 0xFF);
    drawQuad(drawBlue.get(), essl3_shaders::PositionAttrib(), 0.5f);
    EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);
    EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);
    EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);
    EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, gray);
     Draw red if the stencil is 0x2, which should be true in the bottom/right of the middle
     square after the blit.
    glStencilFunc(GL_EQUAL, 0x2, 0xFF);
    drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);
    EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);
    EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);
    EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, GLColor::red);
     Draw green if the stencil is 0x10, which should be left untouched in the outer regions.
    glStencilFunc(GL_EQUAL, 0x10, 0xFF);
    drawQuad(drawGreen.get(), essl3_shaders::PositionAttrib(), 0.5f);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, GLColor::red);
    ASSERT_GL_NO_ERROR();
}
TEST_P ( BlitFramebufferTest , BlitStencilScissoredScaled ) { ANGLE_SKIP_TEST_IF ( IsMetal ( ) && IsIntel ( ) && IsOSX ( ) ) ; constexpr GLint kSize = 256 ; GLTexture destColorbuf ; glBindTexture ( GL_TEXTURE_2D , destColorbuf . get ( ) ) ; glTexStorage2D ( GL_TEXTURE_2D , 1 , GL_RGBA8 , kSize , kSize ) ; GLRenderbuffer destRenderbuf ; glBindRenderbuffer ( GL_RENDERBUFFER , destRenderbuf . get ( ) ) ; glRenderbufferStorage ( GL_RENDERBUFFER , GL_STENCIL_INDEX8 , kSize , kSize ) ; GLFramebuffer destFBO ; glBindFramebuffer ( GL_FRAMEBUFFER , destFBO . get ( ) ) ; glFramebufferTexture2D ( GL_DRAW_FRAMEBUFFER , GL_COLOR_ATTACHMENT0 , GL_TEXTURE_2D , destColorbuf . get ( ) , 0 ) ; glFramebufferRenderbuffer ( GL_DRAW_FRAMEBUFFER , GL_STENCIL_ATTACHMENT , GL_RENDERBUFFER , destRenderbuf . get ( ) ) ; GLColor gray ( 127 , 127 , 127 , 255 ) ; glClearStencil ( 0x10 ) ; glClearColor ( 0.499f , 0.499f , 0.499f , 1.0f ) ; glClear ( GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ) ; EXPECT_PIXEL_COLOR_EQ ( 0 , 0 , gray ) ; EXPECT_PIXEL_COLOR_EQ ( kSize / 2 , kSize / 2 , gray ) ; GLRenderbuffer renderbuf ; glBindRenderbuffer ( GL_RENDERBUFFER , renderbuf . get ( ) ) ; glRenderbufferStorage ( GL_RENDERBUFFER , GL_STENCIL_INDEX8 , kSize , kSize ) ; ANGLE_GL_PROGRAM ( drawRed , essl3_shaders :: vs :: Simple ( ) , essl3_shaders :: fs :: Red ( ) ) ; ANGLE_GL_PROGRAM ( drawGreen , essl3_shaders :: vs :: Simple ( ) , essl3_shaders :: fs :: Green ( ) ) ; ANGLE_GL_PROGRAM ( drawBlue , essl3_shaders :: vs :: Simple ( ) , essl3_shaders :: fs :: Blue ( ) ) ; GLFramebuffer sourceFBO ; glBindFramebuffer ( GL_FRAMEBUFFER , sourceFBO . get ( ) ) ; glFramebufferRenderbuffer ( GL_FRAMEBUFFER , GL_STENCIL_ATTACHMENT , GL_RENDERBUFFER , renderbuf . get ( ) ) ; ASSERT_GLENUM_EQ ( GL_FRAMEBUFFER_COMPLETE , glCheckFramebufferStatus ( GL_FRAMEBUFFER ) ) ; glClearStencil ( 0x1 ) ; glClear ( GL_STENCIL_BUFFER_BIT ) ; glEnable ( GL_SCISSOR_TEST ) ; glEnable ( GL_STENCIL_TEST ) ; glScissor ( kSize / 4 , kSize / 4 , kSize / 2 , kSize / 2 ) ; glStencilFunc ( GL_ALWAYS , 0x2 , 0xFF ) ; glStencilOp ( GL_REPLACE , GL_REPLACE , GL_REPLACE ) ; drawQuad ( drawRed . get ( ) , essl3_shaders :: PositionAttrib ( ) , 0.5f ) ; glBindFramebuffer ( GL_DRAW_FRAMEBUFFER , destFBO . get ( ) ) ; constexpr GLint kBlitSrc [ 2 ] = { -3 * kSize / 8 , 9 * kSize / 8 } ; glBlitFramebuffer ( kBlitSrc [ 0 ] , kBlitSrc [ 0 ] , kBlitSrc [ 1 ] , kBlitSrc [ 1 ] , 0 , 0 , kSize , kSize , GL_STENCIL_BUFFER_BIT , GL_NEAREST ) ; glBindFramebuffer ( GL_FRAMEBUFFER , destFBO . get ( ) ) ; ASSERT_GL_NO_ERROR ( ) ; glDisable ( GL_SCISSOR_TEST ) ; glStencilMask ( 0 ) ; glStencilFunc ( GL_EQUAL , 0x1 , 0xFF ) ; drawQuad ( drawBlue . get ( ) , essl3_shaders :: PositionAttrib ( ) , 0.5f ) ; EXPECT_PIXEL_COLOR_EQ ( 0 , 0 , gray ) ; EXPECT_PIXEL_COLOR_EQ ( kSize - 1 , 0 , gray ) ; EXPECT_PIXEL_COLOR_EQ ( 0 , kSize - 1 , gray ) ; EXPECT_PIXEL_COLOR_EQ ( kSize - 1 , kSize - 1 , gray ) ; EXPECT_PIXEL_COLOR_EQ ( kSize / 4 , kSize / 4 , GLColor :: blue ) ; EXPECT_PIXEL_COLOR_EQ ( kSize / 4 , 3 * kSize / 4 - 1 , GLColor :: blue ) ; EXPECT_PIXEL_COLOR_EQ ( 3 * kSize / 4 - 1 , kSize / 4 , GLColor :: blue ) ; EXPECT_PIXEL_COLOR_EQ ( kSize / 2 , kSize / 2 , gray ) ; EXPECT_PIXEL_COLOR_EQ ( 3 * kSize / 4 - 1 , 3 * kSize / 4 - 1 , gray ) ; glStencilFunc ( GL_EQUAL , 0x2 , 0xFF ) ; drawQuad ( drawRed . get ( ) , essl3_shaders :: PositionAttrib ( ) , 0.5f ) ; EXPECT_PIXEL_COLOR_EQ ( 0 , 0 , gray ) ; EXPECT_PIXEL_COLOR_EQ ( kSize - 1 , 0 , gray ) ; EXPECT_PIXEL_COLOR_EQ ( 0 , kSize - 1 , gray ) ; EXPECT_PIXEL_COLOR_EQ ( kSize - 1 , kSize - 1 , gray ) ; EXPECT_PIXEL_COLOR_EQ ( kSize / 4 , kSize / 4 , GLColor :: blue ) ; EXPECT_PIXEL_COLOR_EQ ( kSize / 4 , 3 * kSize / 4 - 1 , GLColor :: blue ) ; EXPECT_PIXEL_COLOR_EQ ( 3 * kSize / 4 - 1 , kSize / 4 , GLColor :: blue ) ; EXPECT_PIXEL_COLOR_EQ ( kSize / 2 , kSize / 2 , GLColor :: red ) ; EXPECT_PIXEL_COLOR_EQ ( 3 * kSize / 4 - 1 , 3 * kSize / 4 - 1 , GLColor :: red ) ; glStencilFunc ( GL_EQUAL , 0x10 , 0xFF ) ; drawQuad ( drawGreen . get ( ) , essl3_shaders :: PositionAttrib ( ) , 0.5f ) ; EXPECT_PIXEL_COLOR_EQ ( 0 , 0 , GLColor :: green ) ; EXPECT_PIXEL_COLOR_EQ ( kSize - 1 , 0 , GLColor :: green ) ; EXPECT_PIXEL_COLOR_EQ ( 0 , kSize - 1 , GLColor :: green ) ; EXPECT_PIXEL_COLOR_EQ ( kSize - 1 , kSize - 1 , GLColor :: green ) ; EXPECT_PIXEL_COLOR_EQ ( kSize / 4 , kSize / 4 , GLColor :: blue ) ; EXPECT_PIXEL_COLOR_EQ ( kSize / 4 , 3 * kSize / 4 - 1 , GLColor :: blue ) ; EXPECT_PIXEL_COLOR_EQ ( 3 * kSize / 4 - 1 , kSize / 4 , GLColor :: blue ) ; EXPECT_PIXEL_COLOR_EQ ( kSize / 2 , kSize / 2 , GLColor :: red ) ; EXPECT_PIXEL_COLOR_EQ ( 3 * kSize / 4 - 1 , 3 * kSize / 4 - 1 , GLColor :: red ) ; ASSERT_GL_NO_ERROR ( ) ; }
Blit stencil, with scissor and scale it.
Blit stencil with scissor and scale it .
// http://anglebug.com/5106 // Create the destination framebuffer. // Clear the destination buffer with gray and 0x10 stencil. // Create the source framebuffer. // Fill the stencil buffer with 0x1. // Fill a smaller region of the buffer with 0x2. // Blit and scale down into the destination framebuffer (with scissor still enabled). // // Source looks like this: // //     +----|----|----|----+ //     |                   | //     |       0x1         | //     -    +---------+    - //     |    |         |    | //     |    |         |    | //     -    |   0x2   |    - //     |    |         |    | //     |    |         |    | //     -    +---------+    - //     |                   | //     |                   | //     +----|----|----|----+ // // We want the destination to look like this: // //     +----|----|----|----+ //     |                   | //     |       0x10        | //     -    +---------+    - //     |    |  0x1    |    | //     |    |  +------+    | //     -    |  |      |    - //     |    |  | 0x2  |    | //     |    |  |      |    | //     -    +--+------+    - //     |                   | //     |                   | //     +----|----|----|----+ // // The corresponding blit would be: (0, 0, 3/4, 3/4) -> (1/4, 1/4, 3/4, 3/4).  For testing, we // would like to avoid having the destination area and scissor to match.  Using destination // area as (0, 0, 1, 1), and keeping the same scaling, the source area should be // (-3/8, -3/8, 9/8, 9/8). // // Draw blue if the stencil is 0x1, which should be true only in the top and left of the inner // square. // Draw red if the stencil is 0x2, which should be true in the bottom/right of the middle // square after the blit. // Draw green if the stencil is 0x10, which should be left untouched in the outer regions.