// Copyright 2020 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 <cmath>

#include "dawn/tests/DawnTest.h"

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

constexpr static unsigned int kRTSize = 16;

namespace {
    // MipLevel colors, ordering from base level to high level
    // each mipmap of the texture is having a different color
    // so we can check if the sampler anisotropic filtering is fetching
    // from the correct miplevel
    const std::array<RGBA8, 3> colors = {RGBA8::kRed, RGBA8::kGreen, RGBA8::kBlue};
}  // namespace

class SamplerFilterAnisotropicTest : public DawnTest {
  protected:
    void SetUp() override {
        DawnTest::SetUp();
        mRenderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);

        wgpu::ShaderModule vsModule = utils::CreateShaderModule(device, R"(
            struct Uniforms {
                matrix : mat4x4<f32>;
            };

            struct VertexIn {
                @location(0) position : vec4<f32>;
                @location(1) uv : vec2<f32>;
            };

            @group(0) @binding(2) var<uniform> uniforms : Uniforms;

            struct VertexOut {
                @location(0) uv : vec2<f32>;
                @builtin(position) position : vec4<f32>;
            };

            @stage(vertex)
            fn main(input : VertexIn) -> VertexOut {
                var output : VertexOut;
                output.uv = input.uv;
                output.position = uniforms.matrix * input.position;
                return output;
            }
        )");
        wgpu::ShaderModule fsModule = utils::CreateShaderModule(device, R"(
            @group(0) @binding(0) var sampler0 : sampler;
            @group(0) @binding(1) var texture0 : texture_2d<f32>;

            struct FragmentIn {
                @location(0) uv: vec2<f32>;
                @builtin(position) fragCoord : vec4<f32>;
            };

            @stage(fragment)
            fn main(input : FragmentIn) -> @location(0) vec4<f32> {
                return textureSample(texture0, sampler0, input.uv);
            })");

        utils::ComboRenderPipelineDescriptor pipelineDescriptor;
        pipelineDescriptor.vertex.module = vsModule;
        pipelineDescriptor.cFragment.module = fsModule;
        pipelineDescriptor.cBuffers[0].attributeCount = 2;
        pipelineDescriptor.cAttributes[0].format = wgpu::VertexFormat::Float32x4;
        pipelineDescriptor.cAttributes[1].shaderLocation = 1;
        pipelineDescriptor.cAttributes[1].offset = 4 * sizeof(float);
        pipelineDescriptor.cAttributes[1].format = wgpu::VertexFormat::Float32x2;
        pipelineDescriptor.vertex.bufferCount = 1;
        pipelineDescriptor.cBuffers[0].arrayStride = 6 * sizeof(float);
        pipelineDescriptor.cTargets[0].format = mRenderPass.colorFormat;

        mPipeline = device.CreateRenderPipeline(&pipelineDescriptor);
        mBindGroupLayout = mPipeline.GetBindGroupLayout(0);

        InitTexture();
    }

    void InitTexture() {
        const uint32_t mipLevelCount = colors.size();

        const uint32_t textureWidthLevel0 = 1 << (mipLevelCount - 1);
        const uint32_t textureHeightLevel0 = 1 << (mipLevelCount - 1);

        wgpu::TextureDescriptor descriptor;
        descriptor.dimension = wgpu::TextureDimension::e2D;
        descriptor.size.width = textureWidthLevel0;
        descriptor.size.height = textureHeightLevel0;
        descriptor.size.depthOrArrayLayers = 1;
        descriptor.sampleCount = 1;
        descriptor.format = wgpu::TextureFormat::RGBA8Unorm;
        descriptor.mipLevelCount = mipLevelCount;
        descriptor.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::TextureBinding;
        wgpu::Texture texture = device.CreateTexture(&descriptor);

        const uint32_t rowPixels = kTextureBytesPerRowAlignment / sizeof(RGBA8);

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();

        // Populate each mip level with a different color
        for (uint32_t level = 0; level < mipLevelCount; ++level) {
            const uint32_t texWidth = textureWidthLevel0 >> level;
            const uint32_t texHeight = textureHeightLevel0 >> level;

            const RGBA8 color = colors[level];

            std::vector<RGBA8> data(rowPixels * texHeight, color);
            wgpu::Buffer stagingBuffer = utils::CreateBufferFromData(
                device, data.data(), data.size() * sizeof(RGBA8), wgpu::BufferUsage::CopySrc);
            wgpu::ImageCopyBuffer imageCopyBuffer =
                utils::CreateImageCopyBuffer(stagingBuffer, 0, kTextureBytesPerRowAlignment);
            wgpu::ImageCopyTexture imageCopyTexture =
                utils::CreateImageCopyTexture(texture, level, {0, 0, 0});
            wgpu::Extent3D copySize = {texWidth, texHeight, 1};
            encoder.CopyBufferToTexture(&imageCopyBuffer, &imageCopyTexture, &copySize);
        }
        wgpu::CommandBuffer copy = encoder.Finish();
        queue.Submit(1, &copy);

        mTextureView = texture.CreateView();
    }

    // void TestFilterAnisotropic(const FilterAnisotropicTestCase& testCase) {
    void TestFilterAnisotropic(const uint16_t maxAnisotropy) {
        wgpu::Sampler sampler;
        {
            wgpu::SamplerDescriptor descriptor = {};
            descriptor.minFilter = wgpu::FilterMode::Linear;
            descriptor.magFilter = wgpu::FilterMode::Linear;
            descriptor.mipmapFilter = wgpu::FilterMode::Linear;
            descriptor.maxAnisotropy = maxAnisotropy;
            sampler = device.CreateSampler(&descriptor);
        }

        // The transform matrix gives us a slanted plane
        // Tweaking happens at: https://jsfiddle.net/t8k7c95o/5/
        // You can get an idea of what the test looks like at the url rendered by webgl
        std::array<float, 16> transform = {-1.7320507764816284,
                                           1.8322050568049563e-16,
                                           -6.176817699518044e-17,
                                           -6.170640314703498e-17,
                                           -2.1211504944260596e-16,
                                           -1.496108889579773,
                                           0.5043753981590271,
                                           0.5038710236549377,
                                           0,
                                           -43.63650894165039,
                                           -43.232173919677734,
                                           -43.18894577026367,
                                           0,
                                           21.693578720092773,
                                           21.789791107177734,
                                           21.86800193786621};
        wgpu::Buffer transformBuffer = utils::CreateBufferFromData(
            device, transform.data(), sizeof(transform), wgpu::BufferUsage::Uniform);

        wgpu::BindGroup bindGroup = utils::MakeBindGroup(
            device, mBindGroupLayout,
            {{0, sampler}, {1, mTextureView}, {2, transformBuffer, 0, sizeof(transform)}});

        // The plane is scaled on z axis in the transform matrix
        // so uv here is also scaled
        // vertex attribute layout:
        // position : vec4, uv : vec2
        const float vertexData[] = {
            -0.5, 0.5, -0.5, 1, 0, 0,  0.5, 0.5, -0.5, 1, 1, 0, -0.5, 0.5, 0.5, 1, 0, 50,
            -0.5, 0.5, 0.5,  1, 0, 50, 0.5, 0.5, -0.5, 1, 1, 0, 0.5,  0.5, 0.5, 1, 1, 50,
        };
        wgpu::Buffer vertexBuffer = utils::CreateBufferFromData(
            device, vertexData, sizeof(vertexData), wgpu::BufferUsage::Vertex);

        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        {
            wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&mRenderPass.renderPassInfo);
            pass.SetPipeline(mPipeline);
            pass.SetBindGroup(0, bindGroup);
            pass.SetVertexBuffer(0, vertexBuffer);
            pass.Draw(6);
            pass.End();
        }

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

        // https://jsfiddle.net/t8k7c95o/5/
        // (x, y) -> (8, [0,15)) full readpixels result on Win10 Nvidia D3D12 GPU
        // maxAnisotropy: 1
        //  0 - 00 00 00
        //  1 - 00 00 ff
        //  2 - 00 00 ff
        //  3 - 00 00 ff
        //  4 - 00 f9 06
        //  5 - 00 f9 06
        //  6 - f2 0d 00
        //  7 - f2 0d 00
        //  8 - ff 00 00
        //  9 - ff 00 00
        // 10 - ff 00 00
        // 11 - ff 00 00
        // 12 - ff 00 00
        // 13 - ff 00 00
        // 14 - ff 00 00
        // 15 - ff 00 00

        // maxAnisotropy: 2
        //  0 - 00 00 00
        //  1 - 00 00 ff
        //  2 - 00 7e 81
        //  3 - 00 7e 81
        //  4 - ff 00 00
        //  5 - ff 00 00
        //  6 - ff 00 00
        //  7 - ff 00 00
        //  8 - ff 00 00
        //  9 - ff 00 00
        // 10 - ff 00 00
        // 11 - ff 00 00
        // 12 - ff 00 00
        // 13 - ff 00 00
        // 14 - ff 00 00
        // 15 - ff 00 00

        // maxAnisotropy: 16
        //  0 - 00 00 00
        //  1 - 00 00 ff
        //  2 - dd 22 00
        //  3 - dd 22 00
        //  4 - ff 00 00
        //  5 - ff 00 00
        //  6 - ff 00 00
        //  7 - ff 00 00
        //  8 - ff 00 00
        //  9 - ff 00 00
        // 10 - ff 00 00
        // 11 - ff 00 00
        // 12 - ff 00 00
        // 13 - ff 00 00
        // 14 - ff 00 00
        // 15 - ff 00 00

        if (maxAnisotropy >= 16) {
            EXPECT_PIXEL_RGBA8_BETWEEN(colors[0], colors[1], mRenderPass.color, 8, 2);
            EXPECT_PIXEL_RGBA8_EQ(colors[0], mRenderPass.color, 8, 6);
        } else if (maxAnisotropy == 2) {
            EXPECT_PIXEL_RGBA8_BETWEEN(colors[1], colors[2], mRenderPass.color, 8, 2);
            EXPECT_PIXEL_RGBA8_EQ(colors[0], mRenderPass.color, 8, 6);
        } else if (maxAnisotropy <= 1) {
            EXPECT_PIXEL_RGBA8_EQ(colors[2], mRenderPass.color, 8, 2);
            EXPECT_PIXEL_RGBA8_BETWEEN(colors[0], colors[1], mRenderPass.color, 8, 6);
        }
    }

    utils::BasicRenderPass mRenderPass;
    wgpu::BindGroupLayout mBindGroupLayout;
    wgpu::RenderPipeline mPipeline;
    wgpu::TextureView mTextureView;
};

TEST_P(SamplerFilterAnisotropicTest, SlantedPlaneMipmap) {
    // TODO(crbug.com/dawn/740): Test output is wrong with D3D12 + WARP.
    DAWN_SUPPRESS_TEST_IF(IsD3D12() && IsWARP());

    DAWN_SUPPRESS_TEST_IF(IsOpenGL() || IsOpenGLES());
    const uint16_t maxAnisotropyLists[] = {1, 2, 16, 128};
    for (uint16_t t : maxAnisotropyLists) {
        TestFilterAnisotropic(t);
    }
}

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