// 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 "utils/ComboRenderPipelineDescriptor.h"
#include "utils/WGPUHelpers.h"

namespace {

    using Format = wgpu::TextureFormat;
    enum class Check {
        CopyStencil,
        StencilTest,
        CopyDepth,
        DepthTest,
        SampleDepth,
    };

    std::ostream& operator<<(std::ostream& o, Check check) {
        switch (check) {
            case Check::CopyStencil:
                o << "CopyStencil";
                break;
            case Check::StencilTest:
                o << "StencilTest";
                break;
            case Check::CopyDepth:
                o << "CopyDepth";
                break;
            case Check::DepthTest:
                o << "DepthTest";
                break;
            case Check::SampleDepth:
                o << "SampleDepth";
                break;
        }
        return o;
    }

    DAWN_TEST_PARAM_STRUCT(DepthStencilLoadOpTestParams, Format, Check);

    constexpr static uint32_t kRTSize = 16;
    constexpr uint32_t kMipLevelCount = 2u;
    constexpr std::array<float, kMipLevelCount> kDepthValues = {0.125f, 0.875f};
    constexpr std::array<uint16_t, kMipLevelCount> kU16DepthValues = {8192u, 57343u};
    constexpr std::array<uint8_t, kMipLevelCount> kStencilValues = {7u, 3u};

    class DepthStencilLoadOpTests : public DawnTestWithParams<DepthStencilLoadOpTestParams> {
      protected:
        void SetUp() override {
            DawnTestWithParams<DepthStencilLoadOpTestParams>::SetUp();

            DAWN_TEST_UNSUPPORTED_IF(!mIsFormatSupported);

            // Readback of Depth/Stencil textures not fully supported on GL right now.
            // Also depends on glTextureView which is not supported on ES.
            DAWN_SUPPRESS_TEST_IF(IsOpenGL() || IsOpenGLES());

            wgpu::TextureDescriptor descriptor;
            descriptor.size = {kRTSize, kRTSize};
            descriptor.format = GetParam().mFormat;
            descriptor.mipLevelCount = kMipLevelCount;
            descriptor.usage = wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::CopySrc |
                               wgpu::TextureUsage::TextureBinding;

            texture = device.CreateTexture(&descriptor);

            wgpu::TextureViewDescriptor textureViewDesc = {};
            textureViewDesc.mipLevelCount = 1;

            for (uint32_t mipLevel = 0; mipLevel < kMipLevelCount; ++mipLevel) {
                textureViewDesc.baseMipLevel = mipLevel;
                textureViews[mipLevel] = texture.CreateView(&textureViewDesc);

                utils::ComboRenderPassDescriptor renderPassDescriptor({}, textureViews[mipLevel]);
                renderPassDescriptor.cDepthStencilAttachmentInfo.clearDepth =
                    kDepthValues[mipLevel];
                renderPassDescriptor.cDepthStencilAttachmentInfo.clearStencil =
                    kStencilValues[mipLevel];
                renderPassDescriptors.push_back(renderPassDescriptor);
            }
        }

        std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
            switch (GetParam().mFormat) {
                case wgpu::TextureFormat::Depth24UnormStencil8:
                    if (SupportsFeatures({wgpu::FeatureName::Depth24UnormStencil8})) {
                        mIsFormatSupported = true;
                        return {wgpu::FeatureName::Depth24UnormStencil8};
                    }
                    return {};
                case wgpu::TextureFormat::Depth32FloatStencil8:
                    if (SupportsFeatures({wgpu::FeatureName::Depth32FloatStencil8})) {
                        mIsFormatSupported = true;
                        return {wgpu::FeatureName::Depth32FloatStencil8};
                    }
                    return {};
                default:
                    mIsFormatSupported = true;
                    return {};
            }
        }

        void CheckMipLevel(uint32_t mipLevel) {
            uint32_t mipSize = std::max(kRTSize >> mipLevel, 1u);

            switch (GetParam().mCheck) {
                case Check::SampleDepth: {
                    std::vector<float> expectedDepth(mipSize * mipSize, kDepthValues[mipLevel]);
                    ExpectSampledDepthData(texture, mipSize, mipSize, 0, mipLevel,
                                           new detail::ExpectEq<float>(
                                               expectedDepth.data(), expectedDepth.size(), 0.0001))
                        << "sample depth mip " << mipLevel;
                    break;
                }

                case Check::CopyDepth: {
                    if (GetParam().mFormat == wgpu::TextureFormat::Depth16Unorm) {
                        std::vector<uint16_t> expectedDepth(mipSize * mipSize,
                                                            kU16DepthValues[mipLevel]);
                        EXPECT_TEXTURE_EQ(expectedDepth.data(), texture, {0, 0}, {mipSize, mipSize},
                                          mipLevel, wgpu::TextureAspect::DepthOnly)
                            << "copy depth mip " << mipLevel;
                    } else {
                        std::vector<float> expectedDepth(mipSize * mipSize, kDepthValues[mipLevel]);
                        EXPECT_TEXTURE_EQ(expectedDepth.data(), texture, {0, 0}, {mipSize, mipSize},
                                          mipLevel, wgpu::TextureAspect::DepthOnly)
                            << "copy depth mip " << mipLevel;
                    }

                    break;
                }

                case Check::CopyStencil: {
                    std::vector<uint8_t> expectedStencil(mipSize * mipSize,
                                                         kStencilValues[mipLevel]);
                    EXPECT_TEXTURE_EQ(expectedStencil.data(), texture, {0, 0}, {mipSize, mipSize},
                                      mipLevel, wgpu::TextureAspect::StencilOnly)
                        << "copy stencil mip " << mipLevel;
                    break;
                }

                case Check::DepthTest: {
                    std::vector<float> expectedDepth(mipSize * mipSize, kDepthValues[mipLevel]);
                    ExpectAttachmentDepthTestData(texture, GetParam().mFormat, mipSize, mipSize, 0,
                                                  mipLevel, expectedDepth)
                        << "depth test mip " << mipLevel;
                    break;
                }

                case Check::StencilTest: {
                    ExpectAttachmentStencilTestData(texture, GetParam().mFormat, mipSize, mipSize,
                                                    0, mipLevel, kStencilValues[mipLevel])
                        << "stencil test mip " << mipLevel;
                    break;
                }
            }
        }

        wgpu::Texture texture;
        std::array<wgpu::TextureView, kMipLevelCount> textureViews;
        // Vector instead of array because there is no default constructor.
        std::vector<utils::ComboRenderPassDescriptor> renderPassDescriptors;

      private:
        bool mIsFormatSupported = false;
    };

}  // anonymous namespace

// Check that clearing a mip level works at all.
TEST_P(DepthStencilLoadOpTests, ClearMip0) {
    // TODO(https://issuetracker.google.com/issues/204919030): SwiftShader does not clear
    // Depth16Unorm correctly with some values.
    DAWN_SUPPRESS_TEST_IF(IsVulkan() && IsSwiftshader() &&
                          GetParam().mFormat == wgpu::TextureFormat::Depth16Unorm);

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    encoder.BeginRenderPass(&renderPassDescriptors[0]).EndPass();
    wgpu::CommandBuffer commandBuffer = encoder.Finish();
    queue.Submit(1, &commandBuffer);

    CheckMipLevel(0u);
}

// Check that clearing a non-zero mip level works at all.
TEST_P(DepthStencilLoadOpTests, ClearMip1) {
    // TODO(crbug.com/dawn/838): Sampling from the non-zero mip does not work.
    DAWN_SUPPRESS_TEST_IF(IsMetal() && IsIntel() && GetParam().mCheck == Check::SampleDepth);

    // TODO(crbug.com/dawn/838): Copying from the non-zero mip here sometimes returns uninitialized
    // data! (from mip 0 of a previous test run).
    DAWN_SUPPRESS_TEST_IF(IsMetal() && IsIntel() && GetParam().mCheck == Check::CopyDepth);
    DAWN_SUPPRESS_TEST_IF(IsMetal() && IsIntel() && GetParam().mCheck == Check::CopyStencil);

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    encoder.BeginRenderPass(&renderPassDescriptors[1]).EndPass();
    wgpu::CommandBuffer commandBuffer = encoder.Finish();
    queue.Submit(1, &commandBuffer);

    CheckMipLevel(1u);
}

// Clear first mip then the second mip.  Check both mip levels.
TEST_P(DepthStencilLoadOpTests, ClearBothMip0Then1) {
    // TODO(crbug.com/dawn/838): Sampling from the non-zero mip does not work.
    DAWN_SUPPRESS_TEST_IF(IsMetal() && IsIntel() && GetParam().mCheck == Check::SampleDepth);

    // TODO(https://issuetracker.google.com/issues/204919030): SwiftShader does not clear
    // Depth16Unorm correctly with some values.
    DAWN_SUPPRESS_TEST_IF(IsVulkan() && IsSwiftshader() &&
                          GetParam().mFormat == wgpu::TextureFormat::Depth16Unorm);

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    encoder.BeginRenderPass(&renderPassDescriptors[0]).EndPass();
    encoder.BeginRenderPass(&renderPassDescriptors[1]).EndPass();
    wgpu::CommandBuffer commandBuffer = encoder.Finish();
    queue.Submit(1, &commandBuffer);

    CheckMipLevel(0u);
    CheckMipLevel(1u);
}

// Clear second mip then the first mip. Check both mip levels.
TEST_P(DepthStencilLoadOpTests, ClearBothMip1Then0) {
    // TODO(crbug.com/dawn/838): Sampling from the non-zero mip does not work.
    DAWN_SUPPRESS_TEST_IF(IsMetal() && IsIntel() && GetParam().mCheck == Check::SampleDepth);

    // TODO(https://issuetracker.google.com/issues/204919030): SwiftShader does not clear
    // Depth16Unorm correctly with some values.
    DAWN_SUPPRESS_TEST_IF(IsVulkan() && IsSwiftshader() &&
                          GetParam().mFormat == wgpu::TextureFormat::Depth16Unorm);

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    encoder.BeginRenderPass(&renderPassDescriptors[1]).EndPass();
    encoder.BeginRenderPass(&renderPassDescriptors[0]).EndPass();
    wgpu::CommandBuffer commandBuffer = encoder.Finish();
    queue.Submit(1, &commandBuffer);

    CheckMipLevel(0u);
    CheckMipLevel(1u);
}

namespace {

    auto GenerateParams() {
        auto params1 = MakeParamGenerator<DepthStencilLoadOpTestParams>(
            {D3D12Backend(), D3D12Backend({}, {"use_d3d12_render_pass"}), MetalBackend(),
             OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
            {wgpu::TextureFormat::Depth32Float, wgpu::TextureFormat::Depth16Unorm},
            {Check::CopyDepth, Check::DepthTest, Check::SampleDepth});

        auto params2 = MakeParamGenerator<DepthStencilLoadOpTestParams>(
            {D3D12Backend(), D3D12Backend({}, {"use_d3d12_render_pass"}), MetalBackend(),
             OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
            {wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureFormat::Depth24UnormStencil8,
             wgpu::TextureFormat::Depth32FloatStencil8},
            {Check::CopyStencil, Check::StencilTest, Check::DepthTest, Check::SampleDepth});

        std::vector<DepthStencilLoadOpTestParams> allParams;
        allParams.insert(allParams.end(), params1.begin(), params1.end());
        allParams.insert(allParams.end(), params2.begin(), params2.end());

        return allParams;
    }

    INSTANTIATE_TEST_SUITE_P(,
                             DepthStencilLoadOpTests,
                             ::testing::ValuesIn(GenerateParams()),
                             DawnTestBase::PrintToStringParamName("DepthStencilLoadOpTests"));
    GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DepthStencilLoadOpTests);

}  // namespace
