// 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<uint8_t, kMipLevelCount> kStencilValues = {7u, 3u};

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

            // TODO(crbug.com/tint/827): HLSL writer produces invalid code.
            DAWN_SUPPRESS_TEST_IF(IsD3D12() && HasToggleEnabled("use_tint_generator") &&
                                  GetParam().mCheck == Check::SampleDepth);

            // 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::Sampled;

            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);
            }
        }

        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, expectedDepth)
                        << "sample depth mip " << mipLevel;
                    break;
                }

                case Check::CopyDepth: {
                    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;
    };

}  // anonymous namespace

// Check that clearing a mip level works at all.
TEST_P(DepthStencilLoadOpTests, ClearMip0) {
    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);

    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);

    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},
            {Check::CopyDepth, Check::DepthTest, Check::SampleDepth});

        auto params2 = MakeParamGenerator<DepthStencilLoadOpTestParams>(
            {D3D12Backend(), D3D12Backend({}, {"use_d3d12_render_pass"}), MetalBackend(),
             OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
            {wgpu::TextureFormat::Depth24PlusStencil8},
            {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
