Edit

kc3-lang/angle/tests/angle_tests/ViewportTest.cpp

Branch :

  • Show log

    Commit

  • Author : Austin Kinross
    Date : 2014-12-22 12:32:05
    Hash : 4fd18b1b
    Message : Emulate large and negative viewports on D3D11 Feature Level 9_3 Like D3D9, D3D11 Feature Level 9_3 doesn't support large or negative viewports. We have to emulate these in the vertex shader. BUG=angle:858 Change-Id: I2bd53e3921dc3590cc7193164d73596deafca9ea Reviewed-on: https://chromium-review.googlesource.com/236040 Tested-by: Austin Kinross <aukinros@microsoft.com> Reviewed-by: Geoff Lang <geofflang@chromium.org>

  • tests/angle_tests/ViewportTest.cpp
  • #include "ANGLETest.h"
    
    // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
    // D3D11 Feature Level 9 and D3D9 emulate large and negative viewports in the vertex shader. We should test both of these as well as D3D11 Feature Level 10_0+.
    ANGLE_TYPED_TEST_CASE(ViewportTest, ES2_D3D9, ES2_D3D11, ES2_D3D11_FL9_3);
    
    template<typename T>
    class ViewportTest : public ANGLETest
    {
      protected:
        ViewportTest() : ANGLETest(T::GetGlesMajorVersion(), T::GetPlatform())
        {
            setWindowWidth(512);
            setWindowHeight(512);
            setConfigRedBits(8);
            setConfigGreenBits(8);
            setConfigBlueBits(8);
            setConfigAlphaBits(8);
            setConfigDepthBits(24);
    
            mProgram = 0;
        }
    
        void runNonScissoredTest()
        {
            glClearColor(0, 0, 0, 1);
            glClear(GL_COLOR_BUFFER_BIT);
    
            runTest();
        }
    
        void runScissoredTest()
        {
            glClearColor(0, 0, 0, 1);
            glClear(GL_COLOR_BUFFER_BIT);
    
            glEnable(GL_SCISSOR_TEST);
            glScissor(0, getWindowHeight() / 2, getWindowWidth(), getWindowHeight() / 2);
    
            runTest();
        }
    
        void runTest()
        {
            // Firstly ensure that no errors have been hit.
            EXPECT_GL_NO_ERROR();
    
            GLint viewportSize[4];
            glGetIntegerv(GL_VIEWPORT, viewportSize);
    
            // Clear to green. Might be a scissored clear, if scissorSize != window size
            glClearColor(0, 1, 0, 1);
            glClear(GL_COLOR_BUFFER_BIT);
    
            // Draw a red quad centered in the middle of the viewport, with dimensions 25% of the size of the viewport.
            drawQuad(mProgram, "position", 0.5f, 0.25f);
    
            GLint centerViewportX = viewportSize[0] + (viewportSize[2] / 2);
            GLint centerViewportY = viewportSize[1] + (viewportSize[3] / 2);
    
            GLint redQuadLeftSideX   = viewportSize[0] + viewportSize[2] * 3 / 8;
            GLint redQuadRightSideX  = viewportSize[0] + viewportSize[2] * 5 / 8;
            GLint redQuadTopSideY    = viewportSize[1] + viewportSize[3] * 3 / 8;
            GLint redQuadBottomSideY = viewportSize[1] + viewportSize[3] * 5 / 8;
    
            // The midpoint of the viewport should be red.
            checkPixel(centerViewportX, centerViewportY, true);
    
            // Pixels just inside the red quad should be red.
            checkPixel(redQuadLeftSideX,      redQuadTopSideY,        true);
            checkPixel(redQuadLeftSideX,      redQuadBottomSideY - 1, true);
            checkPixel(redQuadRightSideX - 1, redQuadTopSideY,        true);
            checkPixel(redQuadRightSideX - 1, redQuadBottomSideY - 1, true);
    
            // Pixels just outside the red quad shouldn't be red.
            checkPixel(redQuadLeftSideX - 1,  redQuadTopSideY - 1, false);
            checkPixel(redQuadLeftSideX - 1,  redQuadBottomSideY,  false);
            checkPixel(redQuadRightSideX,     redQuadTopSideY - 1, false);
            checkPixel(redQuadRightSideX,     redQuadBottomSideY,  false);
    
            // Pixels just within the viewport shouldn't be red.
            checkPixel(viewportSize[0],                        viewportSize[1],                       false);
            checkPixel(viewportSize[0],                        viewportSize[1] + viewportSize[3] - 1, false);
            checkPixel(viewportSize[0] + viewportSize[2] - 1,  viewportSize[1],                       false);
            checkPixel(viewportSize[0] + viewportSize[2] - 1,  viewportSize[1] + viewportSize[3] - 1, false);
        }
    
        void checkPixel(GLint x, GLint y, GLboolean renderedRed)
        {
            // By default, expect the pixel to be black.
            GLint expectedRedChannel = 0;
            GLint expectedGreenChannel = 0;
    
            GLint scissorSize[4];
            glGetIntegerv(GL_SCISSOR_BOX, scissorSize);
    
            EXPECT_GL_NO_ERROR();
    
            if (scissorSize[0] <= x && x < scissorSize[0] + scissorSize[2]
                && scissorSize[1] <= y && y < scissorSize[1] + scissorSize[3])
            {
                // If the pixel lies within the scissor rect, then it should have been cleared to green.
                // If we rendered a red square on top of it, then the pixel should be red (the green channel will have been reset to 0).
                expectedRedChannel = renderedRed ? 255 : 0;
                expectedGreenChannel = renderedRed ? 0 : 255;
            }
    
            // If the pixel is within the bounds of the window, then we check it. Otherwise we skip it.
            if (0 <= x && x < getWindowWidth() && 0 <= y && y < getWindowHeight())
            {
                EXPECT_PIXEL_EQ(x, y, expectedRedChannel, expectedGreenChannel, 0, 255);
            }
        }
    
        virtual void SetUp()
        {
            ANGLETest::SetUp();
    
            const std::string testVertexShaderSource = SHADER_SOURCE
            (
                attribute highp vec4 position;
    
                void main(void)
                {
                    gl_Position = position;
                }
            );
    
            const std::string testFragmentShaderSource = SHADER_SOURCE
            (
                void main(void)
                {
                    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
                }
            );
    
            mProgram = CompileProgram(testVertexShaderSource, testFragmentShaderSource);
            if (mProgram == 0)
            {
                FAIL() << "shader compilation failed.";
            }
    
            glUseProgram(mProgram);
    
            glClearColor(0, 0, 0, 1);
            glClearDepthf(0.0);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
            // Call glViewport with default parameters.
            glViewport(0, 0, getWindowWidth(), getWindowHeight());
    
            glDisable(GL_DEPTH_TEST);
        }
    
        virtual void TearDown()
        {
            glDeleteProgram(mProgram);
    
            ANGLETest::TearDown();
        }
    
        GLuint mProgram;
    };
    
    TYPED_TEST(ViewportTest, QuarterWindow)
    {
        glViewport(0, 0, getWindowWidth() / 4, getWindowHeight() / 4);
    
        runNonScissoredTest();
    
        runScissoredTest();
    }
    
    TYPED_TEST(ViewportTest, QuarterWindowCentered)
    {
        glViewport(getWindowWidth() * 3 / 8, getWindowHeight() * 3 / 8, getWindowWidth() / 4, getWindowHeight() / 4);
    
        runNonScissoredTest();
    
        runScissoredTest();
    }
    
    TYPED_TEST(ViewportTest, FullWindow)
    {
        glViewport(0, 0, getWindowWidth(), getWindowHeight());
    
        runNonScissoredTest();
    
        runScissoredTest();
    }
    
    TYPED_TEST(ViewportTest, FullWindowOffCenter)
    {
        glViewport(-getWindowWidth() / 2, getWindowHeight() / 2, getWindowWidth(), getWindowHeight());
    
        runNonScissoredTest();
    
        runScissoredTest();
    }
    
    TYPED_TEST(ViewportTest, DoubleWindow)
    {
        glViewport(0, 0, getWindowWidth() * 2, getWindowHeight() * 2);
    
        runNonScissoredTest();
    
        runScissoredTest();
    }
    
    TYPED_TEST(ViewportTest, DoubleWindowCentered)
    {
        glViewport(-getWindowWidth() / 2, -getWindowHeight() / 2, getWindowWidth() * 2, getWindowHeight() * 2);
    
        runNonScissoredTest();
    
        runScissoredTest();
    }
    
    TYPED_TEST(ViewportTest, DoubleWindowOffCenter)
    {
        glViewport(-getWindowWidth() * 3 / 4, getWindowHeight() * 3 / 4, getWindowWidth(), getWindowHeight());
    
        runNonScissoredTest();
    
        runScissoredTest();
    }
    
    TYPED_TEST(ViewportTest, TripleWindow)
    {
        glViewport(0, 0, getWindowWidth() * 3, getWindowHeight() * 3);
    
        runNonScissoredTest();
    
        runScissoredTest();
    }
    
    TYPED_TEST(ViewportTest, TripleWindowCentered)
    {
        glViewport(-getWindowWidth(), -getWindowHeight(), getWindowWidth() * 3, getWindowHeight() * 3);
    
        runNonScissoredTest();
    
        runScissoredTest();
    }
    
    TYPED_TEST(ViewportTest, TripleWindowOffCenter)
    {
        glViewport(-getWindowWidth() * 3 / 2, -getWindowHeight() * 3 / 2, getWindowWidth() * 3, getWindowHeight() * 3);
    
        runNonScissoredTest();
    
        runScissoredTest();
    }