Edit

kc3-lang/angle/src/tests/gl_tests/CubeMapTextureTest.cpp

Branch :

  • Show log

    Commit

  • Author : Le Hoang Quyen
    Date : 2019-11-21 01:19:40
    Hash : 6fcc0bb8
    Message : Metal: Re-add end2end test configs (running test is still disabled) angle_test_instantiate.cpp & angle_test_instantiate_apple.mm: - Disabled metal platform selection on pre-10.13 mac devices for Bug: angleproject:4153 Explicitly disabled tests on metal: - DifferentStencilMasksTest.DrawWithDifferentMask - PointSpritesTest.PointSizeAboveMaxIsClamped - WebGL2ReadOutsideFramebufferTest.CopyTexSubImage3D This requires the crash fix in http://crrev.com/c/1924101 Bug: angleproject:4153 Bug: angleproject:2634 Change-Id: I95046d731a8ba7414cf1a1f4b6f2940282725872 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1926389 Commit-Queue: Jonah Ryan-Davis <jonahr@google.com> Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Jonah Ryan-Davis <jonahr@google.com>

  • src/tests/gl_tests/CubeMapTextureTest.cpp
  • //
    // Copyright 2015 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    
    #include "test_utils/ANGLETest.h"
    #include "test_utils/gl_raii.h"
    
    using namespace angle;
    
    class CubeMapTextureTest : public ANGLETest
    {
      protected:
        CubeMapTextureTest()
        {
            setWindowWidth(256);
            setWindowHeight(256);
            setConfigRedBits(8);
            setConfigGreenBits(8);
            setConfigBlueBits(8);
            setConfigAlphaBits(8);
        }
    
        void testSetUp() override
        {
            mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
            if (mProgram == 0)
            {
                FAIL() << "shader compilation failed.";
            }
    
            mColorLocation = glGetUniformLocation(mProgram, essl1_shaders::ColorUniform());
    
            glUseProgram(mProgram);
    
            glClearColor(0, 0, 0, 0);
            glClearDepthf(0.0);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
            glEnable(GL_BLEND);
            glDisable(GL_DEPTH_TEST);
    
            ASSERT_GL_NO_ERROR();
        }
    
        void testTearDown() override { glDeleteProgram(mProgram); }
    
        void runSampleCoordinateTransformTest(const char *shader);
    
        GLuint mProgram;
        GLint mColorLocation;
    };
    
    // Verify that rendering to the faces of a cube map consecutively will correctly render to each
    // face.
    TEST_P(CubeMapTextureTest, RenderToFacesConsecutively)
    {
        // TODO: Diagnose and fix. http://anglebug.com/2954
        ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsWindows());
    
        // http://anglebug.com/3145
        ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsFuchsia());
    
        // TODO(hqle): Find what wrong with NVIDIA GPU. http://anglebug.com/4138
        ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsMetal());
    
        const GLfloat faceColors[] = {
            1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
            1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
        };
    
        GLuint tex = 0;
        glGenTextures(1, &tex);
        glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
        for (GLenum face = 0; face < 6; face++)
        {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
                         GL_UNSIGNED_BYTE, nullptr);
        }
        EXPECT_GL_NO_ERROR();
    
        GLuint fbo = 0;
        glGenFramebuffers(1, &fbo);
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        EXPECT_GL_NO_ERROR();
    
        for (GLenum face = 0; face < 6; face++)
        {
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                   GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, tex, 0);
            EXPECT_GL_NO_ERROR();
    
            glUseProgram(mProgram);
    
            const GLfloat *faceColor = faceColors + (face * 4);
            glUniform4f(mColorLocation, faceColor[0], faceColor[1], faceColor[2], faceColor[3]);
    
            drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
            EXPECT_GL_NO_ERROR();
        }
    
        for (GLenum face = 0; face < 6; face++)
        {
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                   GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, tex, 0);
            EXPECT_GL_NO_ERROR();
    
            const GLfloat *faceColor = faceColors + (face * 4);
            EXPECT_PIXEL_EQ(0, 0, faceColor[0] * 255, faceColor[1] * 255, faceColor[2] * 255,
                            faceColor[3] * 255);
            EXPECT_GL_NO_ERROR();
        }
    
        glDeleteFramebuffers(1, &fbo);
        glDeleteTextures(1, &tex);
    
        EXPECT_GL_NO_ERROR();
    }
    
    void CubeMapTextureTest::runSampleCoordinateTransformTest(const char *shader)
    {
        // Fails to compile the shader.  anglebug.com/3776
        ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsWindows());
    
        constexpr GLsizei kCubeFaceCount            = 6;
        constexpr GLsizei kCubeFaceSectionCount     = 4;
        constexpr GLsizei kCubeFaceSectionCountSqrt = 2;
    
        constexpr GLColor faceColors[kCubeFaceCount][kCubeFaceSectionCount] = {
            {GLColor(255, 0, 0, 255), GLColor(191, 0, 0, 255), GLColor(127, 0, 0, 255),
             GLColor(63, 0, 0, 255)},
            {GLColor(0, 255, 0, 255), GLColor(0, 191, 0, 255), GLColor(0, 127, 0, 255),
             GLColor(0, 63, 0, 255)},
            {GLColor(0, 0, 255, 255), GLColor(0, 0, 191, 255), GLColor(0, 0, 127, 255),
             GLColor(0, 0, 63, 255)},
            {GLColor(255, 63, 0, 255), GLColor(191, 127, 0, 255), GLColor(127, 191, 0, 255),
             GLColor(63, 255, 0, 255)},
            {GLColor(0, 255, 63, 255), GLColor(0, 191, 127, 255), GLColor(0, 127, 191, 255),
             GLColor(0, 63, 255, 255)},
            {GLColor(63, 0, 255, 255), GLColor(127, 0, 191, 255), GLColor(191, 0, 127, 255),
             GLColor(255, 0, 63, 255)},
        };
    
        constexpr GLsizei kTextureSize = 32;
    
        GLTexture tex;
        glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
        for (GLenum face = 0; face < kCubeFaceCount; face++)
        {
            std::vector<GLColor> faceData(kTextureSize * kTextureSize);
    
            // Create the face with four sections, each with a solid color from |faceColors|.
            for (size_t row = 0; row < kTextureSize / kCubeFaceSectionCountSqrt; ++row)
            {
                for (size_t col = 0; col < kTextureSize / kCubeFaceSectionCountSqrt; ++col)
                {
                    for (size_t srow = 0; srow < kCubeFaceSectionCountSqrt; ++srow)
                    {
                        for (size_t scol = 0; scol < kCubeFaceSectionCountSqrt; ++scol)
                        {
                            size_t r = row + srow * kTextureSize / kCubeFaceSectionCountSqrt;
                            size_t c = col + scol * kTextureSize / kCubeFaceSectionCountSqrt;
                            size_t s = srow * kCubeFaceSectionCountSqrt + scol;
                            faceData[r * kTextureSize + c] = faceColors[face][s];
                        }
                    }
                }
            }
    
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, kTextureSize, kTextureSize,
                         0, GL_RGBA, GL_UNSIGNED_BYTE, faceData.data());
        }
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        EXPECT_GL_NO_ERROR();
    
        GLTexture fboTex;
        glBindTexture(GL_TEXTURE_2D, fboTex);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kCubeFaceCount, kCubeFaceSectionCount, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, nullptr);
    
        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex, 0);
        EXPECT_GL_NO_ERROR();
    
        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), shader);
        glUseProgram(program);
    
        GLint texCubeLocation = glGetUniformLocation(program, "texCube");
        ASSERT_NE(-1, texCubeLocation);
        glUniform1i(texCubeLocation, 0);
    
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
        EXPECT_GL_NO_ERROR();
    
        for (GLenum face = 0; face < kCubeFaceCount; face++)
        {
            // The following table defines the translation from textureCube coordinates to coordinates
            // in each face.  The framebuffer has width 6 and height 4.  Every column corresponding to
            // an x value represents one cube face.  The values in rows are samples from the four
            // sections of the face.
            //
            // Major    Axis Direction Target    sc  tc  ma
            //  +rx  TEXTURE_CUBE_MAP_POSITIVE_X −rz −ry rx
            //  −rx  TEXTURE_CUBE_MAP_NEGATIVE_X  rz −ry rx
            //  +ry  TEXTURE_CUBE_MAP_POSITIVE_Y  rx  rz ry
            //  −ry  TEXTURE_CUBE_MAP_NEGATIVE_Y  rx −rz ry
            //  +rz  TEXTURE_CUBE_MAP_POSITIVE_Z  rx −ry rz
            //  −rz  TEXTURE_CUBE_MAP_NEGATIVE_Z −rx −ry rz
            //
            // This table is used only to determine the direction of growth for s and t.  The shader
            // always generates (row,col) coordinates (0, 0), (0, 1), (1, 0), (1, 1) which is the order
            // the data is uploaded to the faces, but based on the table above, the sample order would
            // be different.
            constexpr size_t faceSampledSections[kCubeFaceCount][kCubeFaceSectionCount] = {
                {3, 2, 1, 0}, {2, 3, 0, 1}, {0, 1, 2, 3}, {2, 3, 0, 1}, {2, 3, 0, 1}, {3, 2, 1, 0},
            };
    
            for (size_t section = 0; section < kCubeFaceSectionCount; ++section)
            {
                const GLColor sectionColor = faceColors[face][faceSampledSections[face][section]];
    
                EXPECT_PIXEL_COLOR_EQ(face, section, sectionColor)
                    << "face " << face << ", section " << section;
            }
        }
        EXPECT_GL_NO_ERROR();
    }
    
    // Verify that cube map sampling follows the rules that map cubemap coordinates to coordinates
    // within each face.  See section 3.7.5 of GLES2.0 (Cube Map Texture Selection).
    TEST_P(CubeMapTextureTest, SampleCoordinateTransform)
    {
        // http://anglebug.com/4092
        ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D9());
        // Create a program that samples from 6x4 directions of the cubemap, draw and verify that the
        // colors match the right color from |faceColors|.
        constexpr char kFS[] = R"(precision mediump float;
    
    uniform samplerCube texCube;
    
    const mat4 coordInSection = mat4(
        vec4(-0.5, -0.5, 0, 0),
        vec4( 0.5, -0.5, 0, 0),
        vec4(-0.5,  0.5, 0, 0),
        vec4( 0.5,  0.5, 0, 0)
    );
    
    void main()
    {
        vec3 coord;
        if (gl_FragCoord.x < 2.0)
        {
            coord.x = gl_FragCoord.x < 1.0 ? 1.0 : -1.0;
            coord.zy = coordInSection[int(gl_FragCoord.y)].xy;
        }
        else if (gl_FragCoord.x < 4.0)
        {
            coord.y = gl_FragCoord.x < 3.0 ? 1.0 : -1.0;
            coord.xz = coordInSection[int(gl_FragCoord.y)].xy;
        }
        else
        {
            coord.z = gl_FragCoord.x < 5.0 ? 1.0 : -1.0;
            coord.xy = coordInSection[int(gl_FragCoord.y)].xy;
        }
    
        gl_FragColor = textureCube(texCube, coord);
    })";
    
        runSampleCoordinateTransformTest(kFS);
    }
    
    // On Android Vulkan, unequal x and y derivatives cause this test to fail.
    TEST_P(CubeMapTextureTest, SampleCoordinateTransformGrad)
    {
        ANGLE_SKIP_TEST_IF(IsAndroid() && IsVulkan());  // anglebug.com/3814
        ANGLE_SKIP_TEST_IF(IsD3D11());                  // anglebug.com/3856
        ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_texture_lod"));
        // http://anglebug.com/4092
        ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D9());
    
        constexpr char kFS[] = R"(#extension GL_EXT_shader_texture_lod : require
    precision mediump float;
    
    uniform samplerCube texCube;
    
    const mat4 coordInSection = mat4(
        vec4(-0.5, -0.5, 0, 0),
        vec4( 0.5, -0.5, 0, 0),
        vec4(-0.5,  0.5, 0, 0),
        vec4( 0.5,  0.5, 0, 0)
    );
    
    void main()
    {
        vec3 coord;
        if (gl_FragCoord.x < 2.0)
        {
            coord.x = gl_FragCoord.x < 1.0 ? 1.0 : -1.0;
            coord.zy = coordInSection[int(gl_FragCoord.y)].xy;
        }
        else if (gl_FragCoord.x < 4.0)
        {
            coord.y = gl_FragCoord.x < 3.0 ? 1.0 : -1.0;
            coord.xz = coordInSection[int(gl_FragCoord.y)].xy;
        }
        else
        {
            coord.z = gl_FragCoord.x < 5.0 ? 1.0 : -1.0;
            coord.xy = coordInSection[int(gl_FragCoord.y)].xy;
        }
    
        gl_FragColor = textureCubeGradEXT(texCube, coord,
                                          vec3(10.0, 10.0, 0.0), vec3(0.0, 10.0, 10.0));
    })";
    
        runSampleCoordinateTransformTest(kFS);
    }
    
    // Use this to select which configurations (e.g. which renderer, which GLES major version) these
    // tests should be run against.
    ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(CubeMapTextureTest);