//
// 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"

#include "common/mathutil.h"
#include "platform/FeaturesD3D.h"

using namespace angle;

class DepthStencilFormatsTestBase : public ANGLETest
{
  protected:
    DepthStencilFormatsTestBase()
    {
        setWindowWidth(128);
        setWindowHeight(128);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }

    bool checkTexImageFormatSupport(GLenum format, GLenum type)
    {
        EXPECT_GL_NO_ERROR();

        GLuint tex = 0;
        glGenTextures(1, &tex);
        glBindTexture(GL_TEXTURE_2D, tex);
        glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, nullptr);
        glDeleteTextures(1, &tex);

        return (glGetError() == GL_NO_ERROR);
    }

    bool checkTexStorageFormatSupport(GLenum internalFormat)
    {
        EXPECT_GL_NO_ERROR();

        GLuint tex = 0;
        glGenTextures(1, &tex);
        glBindTexture(GL_TEXTURE_2D, tex);
        glTexStorage2DEXT(GL_TEXTURE_2D, 1, internalFormat, 1, 1);
        glDeleteTextures(1, &tex);

        return (glGetError() == GL_NO_ERROR);
    }

    bool checkRenderbufferFormatSupport(GLenum internalFormat)
    {
        EXPECT_GL_NO_ERROR();

        GLuint rb = 0;
        glGenRenderbuffers(1, &rb);
        glBindRenderbuffer(GL_RENDERBUFFER, rb);
        glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, 1, 1);
        glDeleteRenderbuffers(1, &rb);

        return (glGetError() == GL_NO_ERROR);
    }

    void verifyDepthRenderBuffer(GLenum internalFormat)
    {
        GLTexture tex;
        glBindTexture(GL_TEXTURE_2D, tex);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
        ASSERT_GL_NO_ERROR();

        GLRenderbuffer rbDepth;
        glBindRenderbuffer(GL_RENDERBUFFER, rbDepth);
        glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, 1, 1);
        ASSERT_GL_NO_ERROR();

        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbDepth);

        EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
        ASSERT_GL_NO_ERROR();

        ANGLE_GL_PROGRAM(programRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_GEQUAL);
        glClearDepthf(0.99f);
        glClearColor(0, 0, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // Pass Depth Test and draw red
        float depthValue = 1.0f;
        drawQuad(programRed.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

        ASSERT_GL_NO_ERROR();

        ANGLE_GL_PROGRAM(programGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());

        // Fail Depth Test and color buffer is unchanged
        depthValue = 0.98f;
        drawQuad(programGreen.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

        ASSERT_GL_NO_ERROR();

        ANGLE_GL_PROGRAM(programBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
        glClearDepthf(0.0f);
        glClear(GL_DEPTH_BUFFER_BIT);

        // Pass Depth Test and draw blue
        depthValue = 0.01f;
        drawQuad(programBlue.get(), essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);

        glDisable(GL_DEPTH_TEST);
        ASSERT_GL_NO_ERROR();
    }

    void testSetUp() override
    {
        constexpr char kVS[] = R"(precision highp float;
attribute vec4 position;
varying vec2 texcoord;

void main()
{
    gl_Position = position;
    texcoord = (position.xy * 0.5) + 0.5;
})";

        constexpr char kFS[] = R"(precision highp float;
uniform sampler2D tex;
varying vec2 texcoord;

void main()
{
    gl_FragColor = texture2D(tex, texcoord);
})";

        mProgram = CompileProgram(kVS, kFS);
        if (mProgram == 0)
        {
            FAIL() << "shader compilation failed.";
        }

        mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
        EXPECT_NE(-1, mTextureUniformLocation);

        glGenTextures(1, &mTexture);
        ASSERT_GL_NO_ERROR();
    }

    void testTearDown() override
    {
        glDeleteProgram(mProgram);
        glDeleteTextures(1, &mTexture);
    }

    GLuint mProgram;
    GLuint mTexture;
    GLint mTextureUniformLocation;
};

class DepthStencilFormatsTest : public DepthStencilFormatsTestBase
{};

class DepthStencilFormatsTestES3 : public DepthStencilFormatsTestBase
{};

TEST_P(DepthStencilFormatsTest, DepthTexture)
{
    bool shouldHaveTextureSupport = (IsGLExtensionEnabled("GL_ANGLE_depth_texture") ||
                                     IsGLExtensionEnabled("GL_OES_depth_texture"));

    EXPECT_EQ(shouldHaveTextureSupport,
              checkTexImageFormatSupport(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT));
    EXPECT_EQ(shouldHaveTextureSupport,
              checkTexImageFormatSupport(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT));

    if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
    {
        EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH_COMPONENT16));
        EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH_COMPONENT32_OES));
    }
}

TEST_P(DepthStencilFormatsTest, PackedDepthStencil)
{
    // Expected to fail in D3D9 if GL_OES_packed_depth_stencil is not present.
    // Expected to fail in D3D11 if GL_OES_packed_depth_stencil or GL_ANGLE_depth_texture is not
    // present.

    bool shouldHaveRenderbufferSupport = IsGLExtensionEnabled("GL_OES_packed_depth_stencil");
    EXPECT_EQ(shouldHaveRenderbufferSupport,
              checkRenderbufferFormatSupport(GL_DEPTH24_STENCIL8_OES));

    bool shouldHaveTextureSupport = (IsGLExtensionEnabled("GL_OES_packed_depth_stencil") &&
                                     IsGLExtensionEnabled("GL_OES_depth_texture")) ||
                                    IsGLExtensionEnabled("GL_ANGLE_depth_texture");
    EXPECT_EQ(shouldHaveTextureSupport,
              checkTexImageFormatSupport(GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES));

    if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
    {
        bool shouldHaveTexStorageSupport = IsGLExtensionEnabled("GL_OES_packed_depth_stencil") ||
                                           IsGLExtensionEnabled("GL_ANGLE_depth_texture");
        EXPECT_EQ(shouldHaveTexStorageSupport,
                  checkTexStorageFormatSupport(GL_DEPTH24_STENCIL8_OES));
    }
}

// This test will initialize a depth texture and then render with it and verify
// pixel correctness.
// This is modeled after webgl-depth-texture.html
TEST_P(DepthStencilFormatsTest, DepthTextureRender)
{
    constexpr char kVS[] = R"(attribute vec4 a_position;
void main()
{
    gl_Position = a_position;
})";

    constexpr char kFS[] = R"(precision mediump float;
uniform sampler2D u_texture;
uniform vec2 u_resolution;
void main()
{
    vec2 texcoord = (gl_FragCoord.xy - vec2(0.5)) / (u_resolution - vec2(1.0));
    gl_FragColor = texture2D(u_texture, texcoord);
})";

    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture") &&
                       !IsGLExtensionEnabled("GL_ANGLE_depth_texture"));

    // http://anglebug.com/3454
    ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsD3D9());

    const int res     = 2;
    const int destRes = 4;
    GLint resolution;

    ANGLE_GL_PROGRAM(program, kVS, kFS);

    glUseProgram(program);
    resolution = glGetUniformLocation(program, "u_resolution");
    ASSERT_NE(-1, resolution);
    glUniform2f(resolution, static_cast<float>(destRes), static_cast<float>(destRes));

    GLuint buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    float verts[] = {
        1, 1, 1, -1, 1, 0, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 0,
    };
    glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);

    // OpenGL ES does not have a FLIPY PixelStore attribute
    // glPixelStorei(GL_UNPACK_FLIP)

    enum ObjType
    {
        GL,
        EXT
    };
    struct TypeInfo
    {
        ObjType obj;
        GLuint attachment;
        GLuint format;
        GLuint type;
        void *data;
        int depthBits;
        int stencilBits;
    };

    GLuint fakeData[10] = {0};

    std::vector<TypeInfo> types = {
        {ObjType::GL, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, fakeData, 16, 0},
        {ObjType::GL, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, fakeData, 16, 0},
        {ObjType::EXT, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8_OES,
         fakeData, 24, 8},
    };

    for (const TypeInfo &type : types)
    {
        GLTexture cubeTex;
        glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);
        ASSERT_GL_NO_ERROR();

        std::vector<GLuint> targets{GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
                                    GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
                                    GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};

        for (const GLuint target : targets)
        {
            glTexImage2D(target, 0, type.format, 1, 1, 0, type.format, type.type, nullptr);
            EXPECT_GL_ERROR(GL_INVALID_OPERATION);
        }

        std::vector<GLuint> filterModes = {GL_LINEAR, GL_NEAREST};

        const bool supportPackedDepthStencilFramebuffer = getClientMajorVersion() >= 3;

        for (const GLuint filterMode : filterModes)
        {
            GLTexture tex;
            glBindTexture(GL_TEXTURE_2D, tex);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterMode);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterMode);

            // test level > 0
            glTexImage2D(GL_TEXTURE_2D, 1, type.format, 1, 1, 0, type.format, type.type, nullptr);
            if (IsGLExtensionEnabled("GL_OES_depth_texture"))
            {
                EXPECT_GL_NO_ERROR();
            }
            else
            {
                EXPECT_GL_ERROR(GL_INVALID_OPERATION);
            }

            // test with data
            glTexImage2D(GL_TEXTURE_2D, 0, type.format, 1, 1, 0, type.format, type.type, type.data);
            if (IsGLExtensionEnabled("GL_OES_depth_texture"))
            {
                EXPECT_GL_NO_ERROR();
            }
            else
            {
                EXPECT_GL_ERROR(GL_INVALID_OPERATION);
            }

            // test copyTexImage2D
            glCopyTexImage2D(GL_TEXTURE_2D, 0, type.format, 0, 0, 1, 1, 0);
            GLuint error = glGetError();
            ASSERT_TRUE(error == GL_INVALID_ENUM || error == GL_INVALID_OPERATION);

            // test real thing
            glTexImage2D(GL_TEXTURE_2D, 0, type.format, res, res, 0, type.format, type.type,
                         nullptr);
            EXPECT_GL_NO_ERROR();

            // test texSubImage2D
            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, type.format, type.type, type.data);
            if (IsGLExtensionEnabled("GL_OES_depth_texture"))
            {
                EXPECT_GL_NO_ERROR();
            }
            else
            {
                EXPECT_GL_ERROR(GL_INVALID_OPERATION);
            }

            // test copyTexSubImage2D
            glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
            EXPECT_GL_ERROR(GL_INVALID_OPERATION);

            // test generateMipmap
            glGenerateMipmap(GL_TEXTURE_2D);
            EXPECT_GL_ERROR(GL_INVALID_OPERATION);

            GLuint fbo = 0;
            glGenFramebuffers(1, &fbo);
            glBindFramebuffer(GL_FRAMEBUFFER, fbo);
            if (type.depthBits > 0 && type.stencilBits > 0 && !supportPackedDepthStencilFramebuffer)
            {
                glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
                EXPECT_GL_NO_ERROR();
                glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex,
                                       0);
                EXPECT_GL_NO_ERROR();
            }
            else
            {
                glFramebufferTexture2D(GL_FRAMEBUFFER, type.attachment, GL_TEXTURE_2D, tex, 0);
                EXPECT_GL_NO_ERROR();
            }

            // Ensure DEPTH_BITS returns >= 16 bits for UNSIGNED_SHORT and UNSIGNED_INT, >= 24
            // UNSIGNED_INT_24_8_WEBGL. If there is stencil, ensure STENCIL_BITS reports >= 8 for
            // UNSIGNED_INT_24_8_WEBGL.

            GLint depthBits = 0;
            glGetIntegerv(GL_DEPTH_BITS, &depthBits);
            EXPECT_GE(depthBits, type.depthBits);

            GLint stencilBits = 0;
            glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
            EXPECT_GE(stencilBits, type.stencilBits);

            // TODO: remove this check if the spec is updated to require these combinations to work.
            if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
            {
                // try adding a color buffer.
                GLuint colorTex = 0;
                glGenTextures(1, &colorTex);
                glBindTexture(GL_TEXTURE_2D, colorTex);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res, res, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                             nullptr);
                glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                       colorTex, 0);
                EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
            }

            EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));

            // use the default texture to render with while we return to the depth texture.
            glBindTexture(GL_TEXTURE_2D, 0);

            /* Setup 2x2 depth texture:
             * 1 0.6 0.8
             * |
             * 0 0.2 0.4
             *    0---1
             */
            const GLfloat d00 = 0.2;
            const GLfloat d01 = 0.4;
            const GLfloat d10 = 0.6;
            const GLfloat d11 = 0.8;
            glEnable(GL_SCISSOR_TEST);
            glScissor(0, 0, 1, 1);
            glClearDepthf(d00);
            glClear(GL_DEPTH_BUFFER_BIT);
            glScissor(1, 0, 1, 1);
            glClearDepthf(d10);
            glClear(GL_DEPTH_BUFFER_BIT);
            glScissor(0, 1, 1, 1);
            glClearDepthf(d01);
            glClear(GL_DEPTH_BUFFER_BIT);
            glScissor(1, 1, 1, 1);
            glClearDepthf(d11);
            glClear(GL_DEPTH_BUFFER_BIT);
            glDisable(GL_SCISSOR_TEST);

            // render the depth texture.
            glBindFramebuffer(GL_FRAMEBUFFER, 0);
            glViewport(0, 0, destRes, destRes);
            glBindTexture(GL_TEXTURE_2D, tex);
            glDisable(GL_DITHER);
            glEnable(GL_DEPTH_TEST);
            glClearColor(1, 0, 0, 1);
            glClearDepthf(1.0);
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
            glDrawArrays(GL_TRIANGLES, 0, 6);

            GLubyte actualPixels[destRes * destRes * 4];
            glReadPixels(0, 0, destRes, destRes, GL_RGBA, GL_UNSIGNED_BYTE, actualPixels);
            const GLfloat eps = 0.002;
            std::vector<GLfloat> expectedMin;
            std::vector<GLfloat> expectedMax;
            if (filterMode == GL_NEAREST)
            {
                GLfloat init[] = {d00, d00, d10, d10, d00, d00, d10, d10,
                                  d01, d01, d11, d11, d01, d01, d11, d11};
                expectedMin.insert(expectedMin.begin(), init, init + 16);
                expectedMax.insert(expectedMax.begin(), init, init + 16);

                for (int i = 0; i < 16; i++)
                {
                    expectedMin[i] = expectedMin[i] - eps;
                    expectedMax[i] = expectedMax[i] + eps;
                }
            }
            else
            {
                GLfloat initMin[] = {
                    d00 - eps, d00, d00, d10 - eps, d00,       d00, d00, d10,
                    d00,       d00, d00, d10,       d01 - eps, d01, d01, d11 - eps,
                };
                GLfloat initMax[] = {
                    d00 + eps, d10, d10, d10 + eps, d01,       d11, d11, d11,
                    d01,       d11, d11, d11,       d01 + eps, d11, d11, d11 + eps,
                };
                expectedMin.insert(expectedMin.begin(), initMin, initMin + 16);
                expectedMax.insert(expectedMax.begin(), initMax, initMax + 16);
            }
            for (int yy = 0; yy < destRes; ++yy)
            {
                for (int xx = 0; xx < destRes; ++xx)
                {
                    const int t        = xx + destRes * yy;
                    const GLfloat was  = (GLfloat)(actualPixels[4 * t] / 255.0);  // 4bpp
                    const GLfloat eMin = expectedMin[t];
                    const GLfloat eMax = expectedMax[t];
                    EXPECT_TRUE(was >= eMin && was <= eMax)
                        << "At " << xx << ", " << yy << ", expected within [" << eMin << ", "
                        << eMax << "] was " << was;
                }
            }

            // check limitations
            // Note: What happens if current attachment type is GL_DEPTH_STENCIL_ATTACHMENT
            // and you try to call glFramebufferTexture2D with GL_DEPTH_ATTACHMENT?
            // The webGL test this code came from expected that to fail.
            // I think due to this line in ES3 spec:
            // GL_INVALID_OPERATION is generated if textarget and texture are not compatible
            // However, that's not the behavior I'm seeing, nor does it seem that a depth_stencil
            // buffer isn't compatible with a depth attachment (e.g. stencil is unused).
            if (type.attachment == GL_DEPTH_ATTACHMENT)
            {
                glBindFramebuffer(GL_FRAMEBUFFER, fbo);
                glFramebufferTexture2D(GL_FRAMEBUFFER, type.attachment, GL_TEXTURE_2D, 0, 0);
                glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
                                       tex, 0);
                EXPECT_GLENUM_NE(GL_NO_ERROR, glGetError());
                EXPECT_GLENUM_NE(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
                glClear(GL_DEPTH_BUFFER_BIT);
                EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
                glBindFramebuffer(GL_FRAMEBUFFER, 0);
                EXPECT_GL_NO_ERROR();
            }
        }
    }
}

// This test will initialize a frame buffer, attaching a color and 16-bit depth buffer,
// render to it with depth testing, and verify pixel correctness.
TEST_P(DepthStencilFormatsTest, DepthBuffer16)
{
    verifyDepthRenderBuffer(GL_DEPTH_COMPONENT16);
}

// This test will initialize a frame buffer, attaching a color and 24-bit depth buffer,
// render to it with depth testing, and verify pixel correctness.
TEST_P(DepthStencilFormatsTest, DepthBuffer24)
{
    bool shouldHaveRenderbufferSupport = IsGLExtensionEnabled("GL_OES_depth24");
    EXPECT_EQ(shouldHaveRenderbufferSupport,
              checkRenderbufferFormatSupport(GL_DEPTH_COMPONENT24_OES));

    if (shouldHaveRenderbufferSupport)
    {
        verifyDepthRenderBuffer(GL_DEPTH_COMPONENT24_OES);
    }
}

TEST_P(DepthStencilFormatsTestES3, DrawWithDepth16)
{
    GLushort data[16];
    for (unsigned int i = 0; i < 16; i++)
    {
        data[i] = std::numeric_limits<GLushort>::max();
    }
    glBindTexture(GL_TEXTURE_2D, mTexture);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT16, 4, 4);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    glUseProgram(mProgram);
    glUniform1i(mTextureUniformLocation, 0);

    glClear(GL_COLOR_BUFFER_BIT);
    drawQuad(mProgram, "position", 0.5f);

    ASSERT_GL_NO_ERROR();

    GLubyte pixel[4];
    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);

    // Only require the red and alpha channels have the correct values, the depth texture extensions
    // leave the green and blue channels undefined
    ASSERT_NEAR(255, pixel[0], 2.0);
    ASSERT_EQ(255, pixel[3]);
}

// This test reproduces a driver bug on Intel windows platforms on driver version
// from 4815 to 4901.
// When rendering with Stencil buffer enabled and depth buffer disabled, large
// viewport will lead to memory leak and driver crash. And the pixel result
// is a random value.
TEST_P(DepthStencilFormatsTestES3, DrawWithLargeViewport)
{
    ANGLE_SKIP_TEST_IF(IsIntel() && (IsOSX() || IsWindows()));

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());

    glEnable(GL_STENCIL_TEST);
    glDisable(GL_DEPTH_TEST);

    // The iteration is to reproduce memory leak when rendering several times.
    for (int i = 0; i < 10; ++i)
    {
        // Create offscreen fbo and its color attachment and depth stencil attachment.
        GLTexture framebufferColorTexture;
        glBindTexture(GL_TEXTURE_2D, framebufferColorTexture);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
        ASSERT_GL_NO_ERROR();

        GLTexture framebufferStencilTexture;
        glBindTexture(GL_TEXTURE_2D, framebufferStencilTexture);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, getWindowWidth(), getWindowHeight());
        ASSERT_GL_NO_ERROR();

        GLFramebuffer fb;
        glBindFramebuffer(GL_FRAMEBUFFER, fb);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                               framebufferColorTexture, 0);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
                               framebufferStencilTexture, 0);

        EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
        ASSERT_GL_NO_ERROR();

        GLint kStencilRef = 4;
        glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
        glStencilFunc(GL_ALWAYS, kStencilRef, 0xFF);

        float viewport[2];
        glGetFloatv(GL_MAX_VIEWPORT_DIMS, viewport);

        glViewport(0, 0, static_cast<GLsizei>(viewport[0]), static_cast<GLsizei>(viewport[1]));
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);

        drawQuad(program.get(), essl1_shaders::PositionAttrib(), 0.0f);
        ASSERT_GL_NO_ERROR();

        glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
        ASSERT_GL_NO_ERROR();
    }
}

// Verify that stencil component of depth texture is uploaded
TEST_P(DepthStencilFormatsTest, VerifyDepthStencilUploadData)
{
    // http://anglebug.com/3683
    // When bug is resolved we can remove this skip.
    ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());

    // http://anglebug.com/3689
    ANGLE_SKIP_TEST_IF(IsWindows() && IsVulkan() && IsAMD());

    bool shouldHaveTextureSupport = (IsGLExtensionEnabled("GL_OES_packed_depth_stencil") &&
                                     IsGLExtensionEnabled("GL_OES_depth_texture")) ||
                                    (getClientMajorVersion() >= 3);

    ANGLE_SKIP_TEST_IF(!shouldHaveTextureSupport ||
                       !checkTexImageFormatSupport(GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES));

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());

    glEnable(GL_STENCIL_TEST);
    glDisable(GL_DEPTH_TEST);
    glDepthMask(GL_FALSE);

    glViewport(0, 0, getWindowWidth(), getWindowHeight());
    glClearColor(0, 0, 0, 1);

    // Create offscreen fbo and its color attachment and depth stencil attachment.
    GLTexture framebufferColorTexture;
    glBindTexture(GL_TEXTURE_2D, framebufferColorTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, nullptr);
    ASSERT_GL_NO_ERROR();

    // drawQuad's depth range is -1.0 to 1.0, so a depth value of 0.5 (0x7fffff) matches a drawQuad
    // depth of 0.0.
    std::vector<GLuint> depthStencilData(getWindowWidth() * getWindowHeight(), 0x7fffffA9);
    GLTexture framebufferStencilTexture;
    glBindTexture(GL_TEXTURE_2D, framebufferStencilTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, getWindowWidth(), getWindowHeight(), 0,
                 GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8_OES, depthStencilData.data());
    ASSERT_GL_NO_ERROR();

    GLFramebuffer fb;
    glBindFramebuffer(GL_FRAMEBUFFER, fb);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                           framebufferColorTexture, 0);

    if (getClientMajorVersion() >= 3)
    {
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
                               framebufferStencilTexture, 0);
        ASSERT_GL_NO_ERROR();
    }
    else
    {
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
                               framebufferStencilTexture, 0);
        ASSERT_GL_NO_ERROR();
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
                               framebufferStencilTexture, 0);
        ASSERT_GL_NO_ERROR();
    }

    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    GLint kStencilRef = 0xA9;
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    glStencilFunc(GL_EQUAL, kStencilRef, 0xFF);

    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);

    glClear(GL_COLOR_BUFFER_BIT);

    drawQuad(program.get(), essl1_shaders::PositionAttrib(), 1.0f);
    ASSERT_GL_NO_ERROR();

    glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
    EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
    ASSERT_GL_NO_ERROR();

    // Check Z values

    glClear(GL_COLOR_BUFFER_BIT);
    glDisable(GL_STENCIL_TEST);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    drawQuad(program.get(), essl1_shaders::PositionAttrib(), -0.1f);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);

    glClear(GL_COLOR_BUFFER_BIT);

    drawQuad(program.get(), essl1_shaders::PositionAttrib(), 0.1f);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::black);
}

// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST_ES2(DepthStencilFormatsTest);
ANGLE_INSTANTIATE_TEST_ES3(DepthStencilFormatsTestES3);

class TinyDepthStencilWorkaroundTest : public ANGLETest
{
  public:
    TinyDepthStencilWorkaroundTest()
    {
        setWindowWidth(512);
        setWindowHeight(512);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }

    // Override the features to enable "tiny" depth/stencil textures.
    void overrideWorkaroundsD3D(FeaturesD3D *features) override
    {
        features->overrideFeatures({"emulate_tiny_stencil_textures"}, true);
    }
};

// Tests that the tiny depth stencil textures workaround does not "stick" depth textures.
// http://anglebug.com/1664
TEST_P(TinyDepthStencilWorkaroundTest, DepthTexturesStick)
{
    // http://anglebug.com/4092
    ANGLE_SKIP_TEST_IF((IsAndroid() && IsOpenGLES()) || (IsLinux() && IsVulkan()));
    ANGLE_SKIP_TEST_IF(isSwiftshader());
    constexpr char kDrawVS[] =
        "#version 100\n"
        "attribute vec3 vertex;\n"
        "void main () {\n"
        "  gl_Position = vec4(vertex.x, vertex.y, vertex.z * 2.0 - 1.0, 1);\n"
        "}\n";

    ANGLE_GL_PROGRAM(drawProgram, kDrawVS, essl1_shaders::fs::Red());

    constexpr char kBlitVS[] =
        "#version 100\n"
        "attribute vec2 vertex;\n"
        "varying vec2 position;\n"
        "void main () {\n"
        "  position = vertex * .5 + .5;\n"
        "  gl_Position = vec4(vertex, 0, 1);\n"
        "}\n";

    constexpr char kBlitFS[] =
        "#version 100\n"
        "precision mediump float;\n"
        "uniform sampler2D texture;\n"
        "varying vec2 position;\n"
        "void main () {\n"
        "  gl_FragColor = vec4 (texture2D (texture, position).rrr, 1.);\n"
        "}\n";

    ANGLE_GL_PROGRAM(blitProgram, kBlitVS, kBlitFS);

    GLint blitTextureLocation = glGetUniformLocation(blitProgram.get(), "texture");
    ASSERT_NE(-1, blitTextureLocation);

    GLTexture colorTex;
    glBindTexture(GL_TEXTURE_2D, colorTex.get());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, nullptr);
    glBindTexture(GL_TEXTURE_2D, 0);

    GLTexture depthTex;
    glBindTexture(GL_TEXTURE_2D, depthTex.get());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
    ASSERT_EQ(getWindowWidth(), getWindowHeight());
    int levels = gl::log2(getWindowWidth());
    for (int mipLevel = 0; mipLevel <= levels; ++mipLevel)
    {
        int size = getWindowWidth() >> mipLevel;
        glTexImage2D(GL_TEXTURE_2D, mipLevel, GL_DEPTH_STENCIL, size, size, 0, GL_DEPTH_STENCIL,
                     GL_UNSIGNED_INT_24_8_OES, nullptr);
    }

    glBindTexture(GL_TEXTURE_2D, 0);

    ASSERT_GL_NO_ERROR();

    GLFramebuffer framebuffer;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex.get(), 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTex.get(), 0);

    ASSERT_GL_NO_ERROR();

    glDepthRangef(0.0f, 1.0f);
    glViewport(0, 0, getWindowWidth(), getWindowHeight());
    glClearColor(0, 0, 0, 1);

    // Draw loop.
    for (unsigned int frame = 0; frame < 3; ++frame)
    {
        // draw into FBO
        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

        glEnable(GL_DEPTH_TEST);

        float depth = ((frame % 2 == 0) ? 0.0f : 1.0f);
        drawQuad(drawProgram.get(), "vertex", depth);

        glBindFramebuffer(GL_FRAMEBUFFER, 0);

        // blit FBO
        glDisable(GL_DEPTH_TEST);

        glUseProgram(blitProgram.get());
        glUniform1i(blitTextureLocation, 0);
        glBindTexture(GL_TEXTURE_2D, depthTex.get());

        drawQuad(blitProgram.get(), "vertex", 0.5f);

        Vector4 depthVec(depth, depth, depth, 1);
        GLColor depthColor(depthVec);

        EXPECT_PIXEL_COLOR_NEAR(0, 0, depthColor, 1);
        ASSERT_GL_NO_ERROR();
    }
}

ANGLE_INSTANTIATE_TEST_ES3(TinyDepthStencilWorkaroundTest);
