// Copyright 2021 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "tests/DawnTest.h"

#include "common/Assert.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/WGPUHelpers.h"

constexpr static unsigned int kRTSize = 1;

class DepthClampingTest : public DawnTest {
  protected:
    void SetUp() override {
        DawnTest::SetUp();
        DAWN_SKIP_TEST_IF(!SupportsExtensions({"depth_clamping"}));

        wgpu::TextureDescriptor renderTargetDescriptor;
        renderTargetDescriptor.size = {kRTSize, kRTSize};
        renderTargetDescriptor.format = wgpu::TextureFormat::RGBA8Unorm;
        renderTargetDescriptor.usage =
            wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc;
        renderTarget = device.CreateTexture(&renderTargetDescriptor);

        renderTargetView = renderTarget.CreateView();

        wgpu::TextureDescriptor depthDescriptor;
        depthDescriptor.dimension = wgpu::TextureDimension::e2D;
        depthDescriptor.size = {kRTSize, kRTSize};
        depthDescriptor.format = wgpu::TextureFormat::Depth24PlusStencil8;
        depthDescriptor.usage = wgpu::TextureUsage::RenderAttachment;
        depthTexture = device.CreateTexture(&depthDescriptor);

        depthTextureView = depthTexture.CreateView();

        vsModule = utils::CreateShaderModule(device, R"(
            [[block]] struct UBO {
                color : vec3<f32>;
                depth : f32;
            };
            [[group(0), binding(0)]] var<uniform> ubo : UBO;
            [[builtin(position)]] var<out> Position : vec4<f32>;

            [[stage(vertex)]] fn main() {
                Position = vec4<f32>(0.0, 0.0, ubo.depth, 1.0);
            })");

        fsModule = utils::CreateShaderModule(device, R"(
            [[block]] struct UBO {
                color : vec3<f32>;
                depth : f32;
            };
            [[group(0), binding(0)]] var<uniform> ubo : UBO;

            [[location(0)]] var<out> fragColor : vec4<f32>;

            [[stage(fragment)]] fn main() {
                fragColor = vec4<f32>(ubo.color, 1.0);
            })");
    }

    std::vector<const char*> GetRequiredExtensions() override {
        std::vector<const char*> requiredExtensions = {};
        if (SupportsExtensions({"depth_clamping"})) {
            requiredExtensions.push_back("depth_clamping");
        }
        return requiredExtensions;
    }

    struct TestSpec {
        wgpu::PrimitiveDepthClampingState* depthClampingState;
        RGBA8 color;
        float depth;
        wgpu::CompareFunction depthCompareFunction;
    };

    // Each test param represents a pair of triangles with a color, depth, stencil value, and
    // depthStencil state, one frontfacing, one backfacing Draw the triangles in order and check the
    // expected colors for the frontfaces and backfaces
    void DoTest(const std::vector<TestSpec>& testParams, const RGBA8& expected) {
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();

        struct TriangleData {
            float color[3];
            float depth;
        };

        utils::ComboRenderPassDescriptor renderPass({renderTargetView}, depthTextureView);
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);

        for (size_t i = 0; i < testParams.size(); ++i) {
            const TestSpec& test = testParams[i];

            TriangleData data = {
                {static_cast<float>(test.color.r) / 255.f, static_cast<float>(test.color.g) / 255.f,
                 static_cast<float>(test.color.b) / 255.f},
                test.depth,
            };
            // Upload a buffer for each triangle's depth and color data
            wgpu::Buffer buffer = utils::CreateBufferFromData(device, &data, sizeof(TriangleData),
                                                              wgpu::BufferUsage::Uniform);

            // Create a pipeline for the triangles with the test spec's params.
            utils::ComboRenderPipelineDescriptor2 descriptor;
            descriptor.primitive.nextInChain = test.depthClampingState;
            descriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;
            descriptor.vertex.module = vsModule;
            descriptor.cFragment.module = fsModule;
            wgpu::DepthStencilState* depthStencil = descriptor.EnableDepthStencil();
            depthStencil->depthWriteEnabled = true;
            depthStencil->depthCompare = test.depthCompareFunction;
            depthStencil->format = wgpu::TextureFormat::Depth24PlusStencil8;

            wgpu::RenderPipeline pipeline = device.CreateRenderPipeline2(&descriptor);

            // Create a bind group for the data
            wgpu::BindGroup bindGroup = utils::MakeBindGroup(
                device, pipeline.GetBindGroupLayout(0), {{0, buffer}});

            pass.SetPipeline(pipeline);
            pass.SetBindGroup(0, bindGroup);
            pass.Draw(1);
        }
        pass.EndPass();

        wgpu::CommandBuffer commands = encoder.Finish();
        queue.Submit(1, &commands);

        EXPECT_PIXEL_RGBA8_EQ(expected, renderTarget,  0, 0) << "Pixel check failed";
    }

    wgpu::Texture renderTarget;
    wgpu::Texture depthTexture;
    wgpu::TextureView renderTargetView;
    wgpu::TextureView depthTextureView;
    wgpu::ShaderModule vsModule;
    wgpu::ShaderModule fsModule;
};

// Test that fragments beyond the far plane are clamped to 1.0 if depth clamping is enabled.
TEST_P(DepthClampingTest, ClampOnBeyondFarPlane) {
    wgpu::PrimitiveDepthClampingState clampingState;
    clampingState.clampDepth = true;

    DoTest(
        {
            // Draw a red triangle at depth 1.
            {
                nullptr, /* depthClampingState */
                RGBA8(255, 0, 0, 255), /* color */
                1.f, /* depth */
                wgpu::CompareFunction::Always,
            },
            // Draw a green triangle at depth 2 which should get clamped to 1.
            {
                &clampingState,
                RGBA8(0, 255, 0, 255), /* color */
                2.f, /* depth */
                wgpu::CompareFunction::Equal,
            },
        },
        // Since we draw the green triangle with an "equal" depth compare function, the resulting
        // fragment should be green.
        RGBA8(0, 255, 0, 255));
}

// Test that fragments beyond the near plane are clamped to 0.0 if depth clamping is enabled.
TEST_P(DepthClampingTest, ClampOnBeyondNearPlane) {
    wgpu::PrimitiveDepthClampingState clampingState;
    clampingState.clampDepth = true;

    DoTest(
        {
            // Draw a red triangle at depth 0.
            {
                nullptr, /* depthClampingState */
                RGBA8(255, 0, 0, 255), /* color */
                0.f, /* depth */
                wgpu::CompareFunction::Always,
            },
            // Draw a green triangle at depth -1 which should get clamped to 0.
            {
                &clampingState,
                RGBA8(0, 255, 0, 255), /* color */
                -1.f, /* depth */
                wgpu::CompareFunction::Equal,
            },
        },
        // Since we draw the green triangle with an "equal" depth compare function, the resulting
        // fragment should be green.
        RGBA8(0, 255, 0, 255));
}

// Test that fragments inside the view frustum are unaffected by depth clamping.
TEST_P(DepthClampingTest, ClampOnInsideViewFrustum) {
    wgpu::PrimitiveDepthClampingState clampingState;
    clampingState.clampDepth = true;

    DoTest(
        {
            {
                &clampingState,
                RGBA8(0, 255, 0, 255), /* color */
                0.5f, /* depth */
                wgpu::CompareFunction::Always,
            },
        },
        RGBA8(0, 255, 0, 255));
}


// Test that fragments outside the view frustum are clipped if depth clamping is disabled.
TEST_P(DepthClampingTest, ClampOffOutsideViewFrustum) {
    wgpu::PrimitiveDepthClampingState clampingState;
    clampingState.clampDepth = false;

    DoTest(
        {
            {
                &clampingState,
                RGBA8(0, 255, 0, 255), /* color */
                2.f, /* depth */
                wgpu::CompareFunction::Always,
            },
            {
                &clampingState,
                RGBA8(0, 255, 0, 255), /* color */
                -1.f, /* depth */
                wgpu::CompareFunction::Always,
            },
        },
        RGBA8(0, 0, 0, 0));
}

// Test that fragments outside the view frustum are clipped if clampDepth is left unspecified.
TEST_P(DepthClampingTest, ClampUnspecifiedOutsideViewFrustum) {
    DoTest(
        {
            {
                nullptr, /* depthClampingState */
                RGBA8(0, 255, 0, 255), /* color */
                -1.f, /* depth */
                wgpu::CompareFunction::Always,
            },
            {
                nullptr, /* depthClampingState */
                RGBA8(0, 255, 0, 255), /* color */
                2.f, /* depth */
                wgpu::CompareFunction::Always,
            },
        },
        RGBA8(0, 0, 0, 0));
}

// Test that fragments are properly clipped or clamped if multiple render pipelines are used
// within the same render pass with differing clampDepth values.
TEST_P(DepthClampingTest, MultipleRenderPipelines) {
    wgpu::PrimitiveDepthClampingState clampingState;
    clampingState.clampDepth = true;

    wgpu::PrimitiveDepthClampingState clippingState;
    clippingState.clampDepth = false;

    DoTest(
        {
            // Draw green with clamping
            {
                &clampingState,
                RGBA8(0, 255, 0, 255), /* color */
                2.f, /* depth */
                wgpu::CompareFunction::Always,
            },
            // Draw red with clipping
            {
                &clippingState,
                RGBA8(255, 0, 0, 255), /* color */
                2.f, /* depth */
                wgpu::CompareFunction::Always,
            },
        },
        RGBA8(0, 255, 0, 255)); // Result should be green
}

DAWN_INSTANTIATE_TEST(DepthClampingTest,
                      D3D12Backend(),
                      MetalBackend(),
                      OpenGLBackend(),
                      OpenGLESBackend(),
                      VulkanBackend());
