//
// Copyright 2022 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.
//
// FragDepthTest:
//   Tests the correctness of gl_FragDepth usage.
//

#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"

using namespace angle;

class FragDepthTest : public ANGLETest<>
{
  protected:
    struct FragDepthTestResources
    {
        GLuint program;
        GLint depthLocation;
        GLTexture colorTexture;
        GLTexture depthTexture;
        GLFramebuffer framebuffer;
    };

    void setupResources(FragDepthTestResources &resources)
    {

        // Writes a fixed depth value and green.
        constexpr char kFS[] =
            R"(#version 300 es
            precision highp float;
            layout(location = 0) out vec4 fragColor;
            uniform float u_depth;
            void main(){
                gl_FragDepth = u_depth;
                fragColor = vec4(0.0, 1.0, 0.0, 1.0);
            })";

        resources.program       = CompileProgram(essl3_shaders::vs::Simple(), kFS);
        resources.depthLocation = glGetUniformLocation(resources.program, "u_depth");

        glBindTexture(GL_TEXTURE_2D, resources.colorTexture);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

        glBindTexture(GL_TEXTURE_2D, resources.depthTexture);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT32F, 1, 1);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

        glBindFramebuffer(GL_FRAMEBUFFER, resources.framebuffer);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                               resources.colorTexture, 0);
    }

    void cleanupResources(FragDepthTestResources &resources) { glDeleteProgram(resources.program); }

    void checkDepthWritten(float expectedDepth, float fsDepth, bool bindDepthBuffer)
    {
        FragDepthTestResources resources;
        setupResources(resources);
        ASSERT_NE(0u, resources.program);
        ASSERT_NE(-1, resources.depthLocation);
        ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
        ASSERT_GL_NO_ERROR();

        glBindFramebuffer(GL_FRAMEBUFFER, resources.framebuffer);
        if (bindDepthBuffer)
        {
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
                                   resources.depthTexture, 0);
            EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

            // Clear to the expected depth so it will be compared to the FS depth with
            // DepthFunc(GL_EQUAL)
            glClearDepthf(expectedDepth);
            glDepthFunc(GL_EQUAL);
            glEnable(GL_DEPTH_TEST);
        }
        else
        {
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
            EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
            glDisable(GL_DEPTH_TEST);
        }
        glUseProgram(resources.program);

        // Clear to red, the FS will write green on success
        glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
        // Clear to the expected depth so it will be compared to the FS depth with
        // DepthFunc(GL_EQUAL)

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glUniform1f(resources.depthLocation, fsDepth);

        drawQuad(resources.program, "a_position", 0.0f);
        EXPECT_GL_NO_ERROR();

        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
        cleanupResources(resources);
    }
};

// Test that writing to gl_FragDepth works
TEST_P(FragDepthTest, DepthBufferBound)
{
    checkDepthWritten(0.5f, 0.5f, true);
}

// Test that writing to gl_FragDepth with no depth buffer works.
TEST_P(FragDepthTest, DepthBufferUnbound)
{
    // Depth test is disabled, so the expected depth should not matter.
    checkDepthWritten(0.f, 0.5f, false);
}

// Test that fragment shader depth writes to a no-depth framebuffer do not fail
// after using a depth-enabled framebuffer with the same program.
TEST_P(FragDepthTest, SwitchToNoDepthFramebuffer)
{
    constexpr char kFS[] = R"(#version 300 es
    out highp vec4 color;
    void main() {
      color = vec4(1.0, 0.0, 0.0, 1.0);
      gl_FragDepth = 1.0;
    })";

    ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);

    // Draw to a depth-enabled framebuffer first
    GLFramebuffer fbo1;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo1);

    GLRenderbuffer rb10;
    glBindRenderbuffer(GL_RENDERBUFFER, rb10);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 128, 128);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb10);

    GLRenderbuffer rb1d;
    glBindRenderbuffer(GL_RENDERBUFFER, rb1d);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32F, 128, 128);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rb1d);

    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    drawQuad(program, "a_position", 0.0f);
    EXPECT_GL_NO_ERROR();

    // Draw to a no-depth framebuffer using the same program
    GLFramebuffer fbo2;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo2);

    GLRenderbuffer rb20;
    glBindRenderbuffer(GL_RENDERBUFFER, rb20);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_R8, 64, 64);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb20);

    EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    drawQuad(program, "a_position", 0.0f);
    EXPECT_GL_NO_ERROR();
}

class FragDepthRedeclarationTest : public ANGLETest<>
{};

// Test gl_FragDepth redeclared as vertex output
TEST_P(FragDepthRedeclarationTest, VSOutput)
{
    constexpr char kVS[] = R"(#version 300 es
#extension GL_EXT_conservative_depth: enable
out highp float gl_FragDepth;
void main() {
    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
    gl_FragDepth = 1.0;
})";

    GLProgram prg;
    prg.makeRaster(kVS, essl3_shaders::fs::Red());
    EXPECT_FALSE(prg.valid());
}

// Test gl_FragDepth redeclared as fragment input
TEST_P(FragDepthRedeclarationTest, FSInput)
{
    constexpr char kFS[] = R"(#version 300 es
#extension GL_EXT_conservative_depth: enable
out highp vec4 color;
in highp float gl_FragDepth;
void main() {
    color = vec4(gl_FragDepth, 0.0, 0.0, 1.0);
})";

    GLProgram prg;
    prg.makeRaster(essl3_shaders::vs::Simple(), kFS);
    EXPECT_FALSE(prg.valid());
}

// Test gl_FragDepth redeclaration with no layout qualifier
TEST_P(FragDepthRedeclarationTest, NoLayout)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_conservative_depth"));

    constexpr char kFS[] = R"(#version 300 es
#extension GL_EXT_conservative_depth: require
out highp vec4 color;
out highp float gl_FragDepth;
void main() {
    color = vec4(1.0, 0.0, 0.0, 1.0);
    gl_FragDepth = 1.0;
})";

    ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
    drawQuad(program, essl3_shaders::PositionAttrib(), 0.0f);
    EXPECT_GL_NO_ERROR();
}

// Test gl_FragDepth redeclaration with depth_any layout qualifier
TEST_P(FragDepthRedeclarationTest, Any)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_conservative_depth"));

    constexpr char kFS[] = R"(#version 300 es
#extension GL_EXT_conservative_depth: require
out highp vec4 color;
layout (depth_any) out highp float gl_FragDepth;
void main() {
    color = vec4(1.0, 0.0, 0.0, 1.0);
    gl_FragDepth = 1.0;
})";

    ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
    drawQuad(program, essl3_shaders::PositionAttrib(), 0.0f);
    EXPECT_GL_NO_ERROR();
}

// Test gl_FragDepth redeclaration with depth_greater layout qualifier
TEST_P(FragDepthRedeclarationTest, Greater)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_conservative_depth"));

    constexpr char kFS[] = R"(#version 300 es
#extension GL_EXT_conservative_depth: require
out highp vec4 color;
layout (depth_greater) out highp float gl_FragDepth;
void main() {
    color = vec4(1.0, 0.0, 0.0, 1.0);
    gl_FragDepth = 1.0;
})";

    ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
    drawQuad(program, essl3_shaders::PositionAttrib(), 0.0f);
    EXPECT_GL_NO_ERROR();
}

// Test gl_FragDepth redeclaration with depth_less layout qualifier
TEST_P(FragDepthRedeclarationTest, Less)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_conservative_depth"));

    constexpr char kFS[] = R"(#version 300 es
#extension GL_EXT_conservative_depth: require
out highp vec4 color;
layout (depth_less) out highp float gl_FragDepth;
void main() {
    color = vec4(1.0, 0.0, 0.0, 1.0);
    gl_FragDepth = 1.0;
})";

    ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
    drawQuad(program, essl3_shaders::PositionAttrib(), 0.0f);
    EXPECT_GL_NO_ERROR();
}

// Test gl_FragDepth redeclaration with depth_unchanged layout qualifier
TEST_P(FragDepthRedeclarationTest, Unchanged)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_conservative_depth"));

    constexpr char kFS[] = R"(#version 300 es
#extension GL_EXT_conservative_depth: require
out highp vec4 color;
layout (depth_unchanged) out highp float gl_FragDepth;
void main() {
    color = vec4(1.0, 0.0, 0.0, 1.0);
    gl_FragDepth = 1.0;
})";

    ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
    drawQuad(program, essl3_shaders::PositionAttrib(), 0.0f);
    EXPECT_GL_NO_ERROR();
}

// Test gl_FragDepth redeclaration with depth_any layout qualifier and gl_FragCoord
TEST_P(FragDepthRedeclarationTest, AnyWithFragCoord)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_conservative_depth"));

    constexpr char kFS[] = R"(#version 300 es
#extension GL_EXT_conservative_depth: require
out highp vec4 color;
layout (depth_any) out highp float gl_FragDepth;
void main() {
    color = vec4(1.0, 0.0, 0.0, 1.0);
    gl_FragDepth = cos(gl_FragCoord.z);
})";

    ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
    drawQuad(program, essl3_shaders::PositionAttrib(), 0.0f);
    EXPECT_GL_NO_ERROR();
}

// Test gl_FragDepth redeclaration with depth_greater layout qualifier and gl_FragCoord
TEST_P(FragDepthRedeclarationTest, GreaterWithFragCoord)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_conservative_depth"));

    constexpr char kFS[] = R"(#version 300 es
#extension GL_EXT_conservative_depth: require
out highp vec4 color;
layout (depth_greater) out highp float gl_FragDepth;
void main() {
    color = vec4(1.0, 0.0, 0.0, 1.0);
    gl_FragDepth = gl_FragCoord.z + 0.5;
})";

    ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
    drawQuad(program, essl3_shaders::PositionAttrib(), 0.0f);
    EXPECT_GL_NO_ERROR();
}

// Test gl_FragDepth redeclaration with depth_less layout qualifier and gl_FragCoord
TEST_P(FragDepthRedeclarationTest, LessWithFragCoord)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_conservative_depth"));

    constexpr char kFS[] = R"(#version 300 es
#extension GL_EXT_conservative_depth: require
out highp vec4 color;
layout (depth_less) out highp float gl_FragDepth;
void main() {
    color = vec4(1.0, 0.0, 0.0, 1.0);
    gl_FragDepth = gl_FragCoord.z - 0.5;
})";

    ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
    drawQuad(program, essl3_shaders::PositionAttrib(), 0.0f);
    EXPECT_GL_NO_ERROR();
}

// Test gl_FragDepth redeclaration with depth_unchanged layout qualifier and gl_FragCoord
TEST_P(FragDepthRedeclarationTest, UnchangedWithFragCoord)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_conservative_depth"));

    constexpr char kFS[] = R"(#version 300 es
#extension GL_EXT_conservative_depth: require
out highp vec4 color;
layout (depth_unchanged) out highp float gl_FragDepth;
void main() {
    color = vec4(1.0, 0.0, 0.0, 1.0);
    gl_FragDepth = gl_FragCoord.z;
})";

    ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
    drawQuad(program, essl3_shaders::PositionAttrib(), 0.0f);
    EXPECT_GL_NO_ERROR();
}

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FragDepthTest);
ANGLE_INSTANTIATE_TEST_ES3(FragDepthTest);

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FragDepthRedeclarationTest);
ANGLE_INSTANTIATE_TEST_ES3(FragDepthRedeclarationTest);
