// 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 <algorithm>
#include <vector>

#include "dawn/tests/DawnTest.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/WGPUHelpers.h"

namespace dawn {
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.UnsetDepthStencilLoadStoreOpsForFormat(GetParam().mFormat);
            renderPassDescriptor.cDepthStencilAttachmentInfo.depthClearValue =
                kDepthValues[mipLevel];
            renderPassDescriptor.cDepthStencilAttachmentInfo.stencilClearValue =
                kStencilValues[mipLevel];
            renderPassDescriptors.push_back(renderPassDescriptor);
        }
    }

    std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
        switch (GetParam().mFormat) {
            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: {
                DAWN_TEST_UNSUPPORTED_IF(utils::IsStencilOnlyFormat(GetParam().mFormat));

                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: {
                DAWN_TEST_UNSUPPORTED_IF(utils::IsStencilOnlyFormat(GetParam().mFormat));

                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,
                                      /* bytesPerRow */ 0, /* tolerance */ uint16_t(1))
                        << "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: {
                DAWN_TEST_UNSUPPORTED_IF(utils::IsStencilOnlyFormat(GetParam().mFormat));

                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(crbug.com/dawn/1828): depth16unorm broken on Apple GPUs.
    DAWN_SUPPRESS_TEST_IF(IsApple() && GetParam().mFormat == wgpu::TextureFormat::Depth16Unorm);

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    encoder.BeginRenderPass(&renderPassDescriptors[0]).End();
    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) {
    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    encoder.BeginRenderPass(&renderPassDescriptors[1]).End();
    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/1828): depth16unorm broken on Apple GPUs.
    DAWN_SUPPRESS_TEST_IF(IsApple() && GetParam().mFormat == wgpu::TextureFormat::Depth16Unorm);

    wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
    encoder.BeginRenderPass(&renderPassDescriptors[0]).End();
    encoder.BeginRenderPass(&renderPassDescriptors[1]).End();
    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/1828): depth16unorm broken on Apple GPUs.
    DAWN_SUPPRESS_TEST_IF(IsApple() && GetParam().mFormat == wgpu::TextureFormat::Depth16Unorm);

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

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

namespace {

auto GenerateParam() {
    auto params1 = MakeParamGenerator<DepthStencilLoadOpTestParams>(
        {D3D11Backend(), 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>(
        {D3D11Backend(), D3D12Backend(), D3D12Backend({}, {"use_d3d12_render_pass"}),
         MetalBackend(), MetalBackend({"metal_use_combined_depth_stencil_format_for_stencil8"}),
         MetalBackend(
             {"metal_use_both_depth_and_stencil_attachments_for_combined_depth_stencil_formats"}),
         OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
        {wgpu::TextureFormat::Depth24PlusStencil8, wgpu::TextureFormat::Depth32FloatStencil8,
         wgpu::TextureFormat::Stencil8},
        {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(GenerateParam()),
                         DawnTestBase::PrintToStringParamName("DepthStencilLoadOpTests"));
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DepthStencilLoadOpTests);

class StencilClearValueOverflowTest : public DepthStencilLoadOpTests {};

// Test when stencilClearValue overflows uint8_t (>255), only the last 8 bits will be applied as the
// stencil clear value in encoder.BeginRenderPass() (currently Dawn only supports 8-bit stencil
// format).
TEST_P(StencilClearValueOverflowTest, StencilClearValueOverFlowUint8) {
    constexpr uint32_t kOverflowedStencilValue = kStencilValues[0] + 0x100;
    renderPassDescriptors[0].cDepthStencilAttachmentInfo.stencilClearValue =
        kOverflowedStencilValue;

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

    CheckMipLevel(0u);
}

// Test when stencilClearValue overflows uint16_t(>65535), only the last 8 bits will be applied as
// the stencil clear value in encoder.BeginRenderPass() (currently Dawn only supports 8-bit stencil
// format).
TEST_P(StencilClearValueOverflowTest, StencilClearValueOverFlowUint16) {
    constexpr uint32_t kOverflowedStencilValue = kStencilValues[0] + 0x10000;
    renderPassDescriptors[0].cDepthStencilAttachmentInfo.stencilClearValue =
        kOverflowedStencilValue;

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

    CheckMipLevel(0u);
}

DAWN_INSTANTIATE_TEST_P(StencilClearValueOverflowTest,
                        {D3D11Backend(), D3D12Backend(),
                         D3D12Backend({}, {"use_d3d12_render_pass"}), MetalBackend(),
                         OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
                        {wgpu::TextureFormat::Depth24PlusStencil8,
                         wgpu::TextureFormat::Depth32FloatStencil8, wgpu::TextureFormat::Stencil8},
                        {Check::CopyStencil, Check::StencilTest});

// Regression tests to reproduce a flaky failure when running whole WebGPU CTS on Intel Gen12 GPUs.
// See crbug.com/dawn/1487 for more details.
using SupportsTextureBinding = bool;
DAWN_TEST_PARAM_STRUCT(DepthTextureClearTwiceTestParams, Format, SupportsTextureBinding);

class DepthTextureClearTwiceTest : public DawnTestWithParams<DepthTextureClearTwiceTestParams> {
  public:
    void RecordClearDepthAspectAtLevel(wgpu::CommandEncoder encoder,
                                       wgpu::Texture depthTexture,
                                       uint32_t level,
                                       float clearValue) {
        wgpu::TextureViewDescriptor viewDescriptor = {};
        viewDescriptor.baseArrayLayer = 0;
        viewDescriptor.arrayLayerCount = 1;
        viewDescriptor.baseMipLevel = level;
        viewDescriptor.mipLevelCount = 1;
        wgpu::TextureView view = depthTexture.CreateView(&viewDescriptor);

        wgpu::RenderPassDescriptor renderPassDescriptor = {};
        renderPassDescriptor.colorAttachmentCount = 0;

        wgpu::RenderPassDepthStencilAttachment depthStencilAttachment = {};
        depthStencilAttachment.view = view;
        depthStencilAttachment.depthClearValue = clearValue;
        depthStencilAttachment.depthLoadOp = wgpu::LoadOp::Clear;
        depthStencilAttachment.depthStoreOp = wgpu::StoreOp::Store;

        if (!utils::IsDepthOnlyFormat(GetParam().mFormat)) {
            depthStencilAttachment.stencilLoadOp = wgpu::LoadOp::Load;
            depthStencilAttachment.stencilStoreOp = wgpu::StoreOp::Store;
        }

        renderPassDescriptor.depthStencilAttachment = &depthStencilAttachment;
        wgpu::RenderPassEncoder renderPass = encoder.BeginRenderPass(&renderPassDescriptor);
        renderPass.End();
    }

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

    bool mIsFormatSupported = false;
};

TEST_P(DepthTextureClearTwiceTest, ClearDepthAspectTwice) {
    DAWN_SUPPRESS_TEST_IF(!mIsFormatSupported);

    constexpr uint32_t kSize = 64;
    constexpr uint32_t kLevelCount = 5;

    wgpu::TextureFormat depthFormat = GetParam().mFormat;

    wgpu::TextureDescriptor descriptor;
    descriptor.size = {kSize, kSize};
    descriptor.format = depthFormat;
    descriptor.mipLevelCount = kLevelCount;

    // The toggle "d3d12_force_initialize_copyable_depth_stencil_texture_on_creation" is not related
    // to this test as we don't specify wgpu::TextureUsage::CopyDst in the test.
    descriptor.usage = wgpu::TextureUsage::RenderAttachment;
    if (GetParam().mSupportsTextureBinding) {
        descriptor.usage |= wgpu::TextureUsage::TextureBinding;
    }
    wgpu::Texture depthTexture = device.CreateTexture(&descriptor);

    // First, clear all the subresources to 0.
    {
        constexpr float kClearValue = 0.f;
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        for (uint32_t level = 0; level < kLevelCount; ++level) {
            RecordClearDepthAspectAtLevel(encoder, depthTexture, level, kClearValue);
        }
        wgpu::CommandBuffer commandBuffer = encoder.Finish();
        queue.Submit(1, &commandBuffer);
    }

    // Then, clear several mipmap levels to 0.8.
    {
        constexpr float kClearValue = 0.8f;
        constexpr std::array<uint32_t, 2> kLevelsToSet = {2u, 4u};
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        for (uint32_t level : kLevelsToSet) {
            RecordClearDepthAspectAtLevel(encoder, depthTexture, level, kClearValue);
        }
        wgpu::CommandBuffer commandBuffer = encoder.Finish();
        queue.Submit(1, &commandBuffer);
    }

    // Check if the data in remaining mipmap levels is still 0.
    {
        constexpr std::array<uint32_t, 3> kLevelsToTest = {0, 1u, 3u};
        for (uint32_t level : kLevelsToTest) {
            uint32_t sizeAtLevel = kSize >> level;
            std::vector<float> expectedValue(sizeAtLevel * sizeAtLevel, 0.f);
            ExpectAttachmentDepthTestData(depthTexture, GetParam().mFormat, sizeAtLevel,
                                          sizeAtLevel, 0, level, expectedValue);
        }
    }
}

DAWN_INSTANTIATE_TEST_P(DepthTextureClearTwiceTest,
                        {D3D11Backend(), D3D12Backend(), MetalBackend(), OpenGLBackend(),
                         OpenGLESBackend(), VulkanBackend()},
                        {wgpu::TextureFormat::Depth16Unorm, wgpu::TextureFormat::Depth24Plus,
                         wgpu::TextureFormat::Depth32Float,
                         wgpu::TextureFormat::Depth32FloatStencil8,
                         wgpu::TextureFormat::Depth24PlusStencil8},
                        {true, false});

}  // anonymous namespace
}  // namespace dawn
