Edit

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

Branch :

  • Show log

    Commit

  • Author : James Darpinian
    Date : 2020-12-29 16:25:54
    Hash : ebf00703
    Message : angle_end2end_tests passes on iOS! Miscellaneous test skips and fixes for iOS. Bug: angleproject:5417 Bug: angleproject:5491 Change-Id: Id0785e6243949fc756e4d7923dbbe77a411052f3 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2606656 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Kenneth Russell <kbr@chromium.org> Commit-Queue: James Darpinian <jdarpinian@chromium.org>

  • src/tests/gl_tests/BlendMinMaxTest.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"
    
    using namespace angle;
    
    class BlendMinMaxTest : public ANGLETest
    {
      protected:
        BlendMinMaxTest()
        {
            setWindowWidth(128);
            setWindowHeight(128);
            setConfigRedBits(8);
            setConfigGreenBits(8);
            setConfigBlueBits(8);
            setConfigAlphaBits(8);
            setConfigDepthBits(24);
    
            mProgram           = 0;
            mColorLocation     = -1;
            mFramebuffer       = 0;
            mColorRenderbuffer = 0;
        }
    
        struct Color
        {
            float values[4];
        };
    
        static float getExpected(bool blendMin, float curColor, float prevColor)
        {
            return blendMin ? std::min(curColor, prevColor) : std::max(curColor, prevColor);
        }
    
        void runTest(GLenum colorFormat, GLenum type)
        {
            ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                               !IsGLExtensionEnabled("GL_EXT_blend_minmax"));
    
            SetUpFramebuffer(colorFormat);
    
            int minValue = 0;
            int maxValue = 1;
            if (type == GL_FLOAT)
            {
                minValue = -1024;
                maxValue = 1024;
            }
    
            const size_t colorCount = 128;
            Color colors[colorCount];
            for (size_t i = 0; i < colorCount; i++)
            {
                for (size_t j = 0; j < 4; j++)
                {
                    colors[i].values[j] =
                        static_cast<float>(minValue + (rand() % (maxValue - minValue)));
                }
            }
    
            float prevColor[4];
            for (size_t i = 0; i < colorCount; i++)
            {
                const Color &color = colors[i];
                glUseProgram(mProgram);
                glUniform4f(mColorLocation, color.values[0], color.values[1], color.values[2],
                            color.values[3]);
    
                bool blendMin = (rand() % 2 == 0);
                glBlendEquation(blendMin ? GL_MIN : GL_MAX);
    
                drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
    
                float pixel[4];
                if (type == GL_UNSIGNED_BYTE)
                {
                    GLubyte ubytePixel[4];
                    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, ubytePixel);
                    for (size_t componentIdx = 0; componentIdx < ArraySize(pixel); componentIdx++)
                    {
                        pixel[componentIdx] = ubytePixel[componentIdx] / 255.0f;
                    }
                }
                else if (type == GL_FLOAT)
                {
                    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, pixel);
                }
                else
                {
                    FAIL() << "Unexpected pixel type";
                }
    
                if (i > 0)
                {
                    const float errorRange = 1.0f / 255.0f;
                    for (size_t componentIdx = 0; componentIdx < ArraySize(pixel); componentIdx++)
                    {
                        EXPECT_NEAR(
                            getExpected(blendMin, color.values[componentIdx], prevColor[componentIdx]),
                            pixel[componentIdx], errorRange)
                            << " blendMin=" << blendMin << " componentIdx=" << componentIdx << std::endl
                            << " color.values[0]=" << color.values[0]
                            << " prevColor[0]=" << prevColor[0] << std::endl
                            << " color.values[1]=" << color.values[1]
                            << " prevColor[1]=" << prevColor[1] << std::endl
                            << " color.values[2]=" << color.values[2]
                            << " prevColor[2]=" << prevColor[2] << std::endl
                            << " color.values[3]=" << color.values[3]
                            << " prevColor[3]=" << prevColor[3];
                    }
                }
    
                memcpy(prevColor, pixel, sizeof(pixel));
            }
        }
    
        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);
        }
    
        void SetUpFramebuffer(GLenum colorFormat)
        {
            glGenFramebuffers(1, &mFramebuffer);
            glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
    
            glGenRenderbuffers(1, &mColorRenderbuffer);
            glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer);
            glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, getWindowWidth(), getWindowHeight());
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
                                      mColorRenderbuffer);
    
            glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
            glClear(GL_COLOR_BUFFER_BIT);
    
            ASSERT_GL_NO_ERROR();
        }
    
        void testTearDown() override
        {
            glDeleteProgram(mProgram);
            glDeleteFramebuffers(1, &mFramebuffer);
            glDeleteRenderbuffers(1, &mColorRenderbuffer);
        }
    
        GLuint mProgram;
        GLint mColorLocation;
    
        GLuint mFramebuffer;
        GLuint mColorRenderbuffer;
    };
    
    TEST_P(BlendMinMaxTest, RGBA8)
    {
        runTest(GL_RGBA8, GL_UNSIGNED_BYTE);
    }
    
    TEST_P(BlendMinMaxTest, RGBA32F)
    {
        ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 || !IsGLExtensionEnabled("GL_EXT_float_blend") ||
                           !IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
    
        // Ignore SDK layers messages on D3D11 FL 9.3 (http://anglebug.com/1284)
        ANGLE_SKIP_TEST_IF(IsD3D11_FL93());
    
        runTest(GL_RGBA32F, GL_FLOAT);
    }
    
    TEST_P(BlendMinMaxTest, RGBA16F)
    {
        ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
                           !IsGLExtensionEnabled("GL_EXT_color_buffer_half_float"));
        // http://anglebug.com/4092
        ANGLE_SKIP_TEST_IF((IsAndroid() && IsVulkan()) || isSwiftshader());
    
        // http://anglebug.com/4185
        ANGLE_SKIP_TEST_IF(IsMetal());
    
        // TODO(anglebug.com/5491) Context.cpp disallows GL_EXT_color_buffer_half_float on iOS because
        // it doesn't support GL_EXT_color_buffer_float.
        ANGLE_SKIP_TEST_IF(IsIOS() && IsOpenGLES());
    
        runTest(GL_RGBA16F, GL_FLOAT);
    }
    
    // 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(BlendMinMaxTest);