// Copyright 2022 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/common/Math.h"
#include "dawn/tests/DawnTest.h"
#include "dawn/utils/ComboRenderPipelineDescriptor.h"
#include "dawn/utils/WGPUHelpers.h"

namespace dawn {
namespace {

// 2D array textures with particular dimensions may corrupt on some devices. This test creates some
// 2d-array textures with different dimensions, and test them one by one. For each sub-test, the
// tested texture is written via different methods, then read back from the texture and verify the
// data.

enum class WriteType {
    ClearTexture,
    WriteTexture,    // Write the tested texture via writeTexture API
    B2TCopy,         // Write the tested texture via B2T copy
    RenderConstant,  // Write the tested texture via rendering the whole rectangle with solid color
                     // (0xFFFFFFFF)
    RenderFromTextureSample,  // Write the tested texture via sampling from a temp texture and
                              // writing the sampled data
    RenderFromTextureLoad     // Write the tested texture via textureLoad() from a temp texture and
                              // writing the loaded data
};

constexpr wgpu::TextureFormat kDefaultFormat = wgpu::TextureFormat::RGBA8Unorm;
constexpr uint32_t kDefaultHeight = 100u;
constexpr uint32_t kDefaultArrayLayerCount = 2u;
constexpr uint32_t kDefaultMipLevelCount = 1u;
constexpr uint32_t kDefaultSampleCount = 1u;
constexpr WriteType kDefaultWriteType = WriteType::B2TCopy;

std::ostream& operator<<(std::ostream& o, WriteType writeType) {
    switch (writeType) {
        case WriteType::ClearTexture:
            o << "ClearTexture";
            break;
        case WriteType::WriteTexture:
            o << "WriteTexture";
            break;
        case WriteType::B2TCopy:
            o << "B2TCopy";
            break;
        case WriteType::RenderConstant:
            o << "RenderConstant";
            break;
        case WriteType::RenderFromTextureSample:
            o << "RenderFromTextureSample";
            break;
        case WriteType::RenderFromTextureLoad:
            o << "RenderFromTextureLoad";
            break;
    }
    return o;
}

using TextureFormat = wgpu::TextureFormat;
using TextureWidth = uint32_t;
using TextureHeight = uint32_t;
using ArrayLayerCount = uint32_t;
using MipLevelCount = uint32_t;
using SampleCount = uint32_t;

DAWN_TEST_PARAM_STRUCT(TextureCorruptionTestsParams,
                       TextureFormat,
                       TextureWidth,
                       TextureHeight,
                       ArrayLayerCount,
                       MipLevelCount,
                       SampleCount,
                       WriteType);

class TextureCorruptionTests : public DawnTestWithParams<TextureCorruptionTestsParams> {
  protected:
    virtual std::ostringstream& DoSingleTest(wgpu::Texture texture,
                                             const wgpu::Extent3D textureSize,
                                             uint32_t depthOrArrayLayer,
                                             uint32_t mipLevel,
                                             uint32_t sampleCount,
                                             uint32_t srcValue,
                                             wgpu::TextureFormat format) {
        wgpu::Extent3D levelSize = textureSize;
        if (mipLevel > 0) {
            levelSize.width = std::max(textureSize.width >> mipLevel, 1u);
            levelSize.height = std::max(textureSize.height >> mipLevel, 1u);
        }
        uint32_t bytesPerTexel = utils::GetTexelBlockSizeInBytes(format);
        uint32_t bytesPerRow = Align(levelSize.width * bytesPerTexel, 256);
        uint64_t bufferSize = bytesPerRow * levelSize.height;
        wgpu::BufferDescriptor descriptor;
        descriptor.size = bufferSize;
        descriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
        wgpu::Buffer buffer = device.CreateBuffer(&descriptor);
        wgpu::Buffer resultBuffer = device.CreateBuffer(&descriptor);

        wgpu::ImageCopyTexture imageCopyTexture =
            utils::CreateImageCopyTexture(texture, mipLevel, {0, 0, depthOrArrayLayer});
        wgpu::ImageCopyBuffer imageCopyBuffer =
            utils::CreateImageCopyBuffer(buffer, 0, bytesPerRow);
        wgpu::ImageCopyBuffer imageCopyResult =
            utils::CreateImageCopyBuffer(resultBuffer, 0, bytesPerRow);

        WriteType type = GetParam().mWriteType;

        // Fill data into a buffer
        wgpu::Extent3D copySize = {levelSize.width, levelSize.height, 1};

        // Data is stored in a uint32_t vector, so a single texel may require multiple vector
        // elements for some formats or multiple texels may be combined into one vector element.
        uint32_t elementNumPerTexel = 1;
        uint32_t copyWidth = copySize.width;
        if (bytesPerTexel >= sizeof(uint32_t)) {
            elementNumPerTexel = bytesPerTexel / sizeof(uint32_t);
        } else {
            copyWidth = copyWidth * bytesPerTexel / sizeof(uint32_t);
        }

        uint32_t elementNumPerRow = bytesPerRow / sizeof(uint32_t);
        uint32_t elementNumInTotal = bufferSize / sizeof(uint32_t);
        std::vector<uint32_t> data(elementNumInTotal, 0);
        for (uint32_t i = 0; i < copySize.height; ++i) {
            for (uint32_t j = 0; j < copyWidth; ++j) {
                for (uint32_t k = 0; k < elementNumPerTexel; ++k) {
                    if (type == WriteType::RenderFromTextureSample ||
                        type == WriteType::RenderConstant) {
                        // Fill a simple and constant value (0xFFFFFFFF) in the whole buffer for
                        // texture sampling and rendering because either sampling operation will
                        // lead to precision loss or rendering a solid color is easier to implement
                        // and compare.
                        DAWN_ASSERT(elementNumPerTexel == 1);
                        data[i * elementNumPerRow + j] = 0xFFFFFFFF;
                    } else if (type != WriteType::ClearTexture) {
                        data[i * elementNumPerRow + j * elementNumPerTexel + k] = srcValue;
                        srcValue++;
                    }
                }
            }
        }

        // Write data into the given layer via various write types
        wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
        switch (type) {
            case WriteType::B2TCopy: {
                queue.WriteBuffer(buffer, 0, data.data(), bufferSize);
                encoder.CopyBufferToTexture(&imageCopyBuffer, &imageCopyTexture, &copySize);
                break;
            }
            case WriteType::WriteTexture: {
                wgpu::TextureDataLayout textureDataLayout =
                    utils::CreateTextureDataLayout(0, bytesPerRow);
                queue.WriteTexture(&imageCopyTexture, data.data(), bufferSize, &textureDataLayout,
                                   &copySize);
                break;
            }
            case WriteType::RenderConstant:
            case WriteType::RenderFromTextureSample:
            case WriteType::RenderFromTextureLoad: {
                // Write data into a single layer temp texture and read from this texture if needed
                DAWN_ASSERT(format == wgpu::TextureFormat::RGBA8Unorm);
                wgpu::TextureView tempView;
                if (type != WriteType::RenderConstant) {
                    wgpu::Texture tempTexture = Create2DTexture(copySize, format, 1, 1);
                    wgpu::ImageCopyTexture imageCopyTempTexture =
                        utils::CreateImageCopyTexture(tempTexture, 0, {0, 0, 0});
                    wgpu::TextureDataLayout textureDataLayout =
                        utils::CreateTextureDataLayout(0, bytesPerRow);
                    queue.WriteTexture(&imageCopyTempTexture, data.data(), bufferSize,
                                       &textureDataLayout, &copySize);
                    tempView = tempTexture.CreateView();
                }

                // Write into the specified layer of a 2D array texture
                wgpu::TextureViewDescriptor viewDesc;
                viewDesc.format = format;
                viewDesc.dimension = wgpu::TextureViewDimension::e2D;
                viewDesc.baseMipLevel = 0;
                viewDesc.mipLevelCount = 1;
                viewDesc.baseArrayLayer = depthOrArrayLayer;
                viewDesc.arrayLayerCount = 1;
                CreatePipelineAndRender(texture.CreateView(&viewDesc), tempView, encoder, type,
                                        format);
                break;
            }
            default:
                break;
        }

        // Verify the data in texture via a T2B copy and comparison
        encoder.CopyTextureToBuffer(&imageCopyTexture, &imageCopyResult, &copySize);
        wgpu::CommandBuffer commands = encoder.Finish();
        queue.Submit(1, &commands);
        return EXPECT_BUFFER_U32_RANGE_EQ(data.data(), resultBuffer, 0, elementNumInTotal);
    }

    void CreatePipelineAndRender(wgpu::TextureView renderView,
                                 wgpu::TextureView samplerView,
                                 wgpu::CommandEncoder encoder,
                                 WriteType type,
                                 wgpu::TextureFormat format) {
        utils::ComboRenderPipelineDescriptor pipelineDescriptor;
        pipelineDescriptor.cTargets[0].format = format;

        // Draw the whole texture (a rectangle) via two triangles
        pipelineDescriptor.vertex.module = utils::CreateShaderModule(device, R"(
            @vertex
            fn main(@builtin(vertex_index) VertexIndex : u32) -> @builtin(position) vec4f {
                var pos = array(
                    vec2f(-1.0,  1.0),
                    vec2f(-1.0, -1.0),
                    vec2f( 1.0,  1.0),
                    vec2f( 1.0,  1.0),
                    vec2f(-1.0, -1.0),
                    vec2f( 1.0, -1.0));
                return vec4f(pos[VertexIndex], 0.0, 1.0);
            })");

        if (type == WriteType::RenderConstant) {
            pipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, R"(
            @fragment
            fn main(@builtin(position) FragCoord : vec4f) -> @location(0) vec4f {
                return vec4f(1.0, 1.0, 1.0, 1.0);
            })");
        } else if (type == WriteType::RenderFromTextureSample) {
            pipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, R"(
            @group(0) @binding(0) var samp : sampler;
            @group(0) @binding(1) var tex : texture_2d<f32>;

            @fragment
            fn main(@builtin(position) FragCoord : vec4f) -> @location(0) vec4f {
                return textureSample(tex, samp, FragCoord.xy);
            })");
        } else {
            pipelineDescriptor.cFragment.module = utils::CreateShaderModule(device, R"(
            @group(0) @binding(0) var tex : texture_2d<f32>;

            @fragment
            fn main(@builtin(position) Fragcoord: vec4f) -> @location(0) vec4f {
                return textureLoad(tex, vec2i(Fragcoord.xy), 0);
            })");
        }

        wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&pipelineDescriptor);

        utils::ComboRenderPassDescriptor renderPassDescriptor({renderView});
        wgpu::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPassDescriptor);
        pass.SetPipeline(pipeline);
        if (type != WriteType::RenderConstant) {
            wgpu::BindGroup bindGroup;
            if (type == WriteType::RenderFromTextureLoad) {
                bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                                 {{0, samplerView}});
            } else {
                bindGroup = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0),
                                                 {{0, device.CreateSampler()}, {1, samplerView}});
            }
            pass.SetBindGroup(0, bindGroup);
        }
        pass.Draw(6);
        pass.End();
    }

    wgpu::Texture Create2DTexture(const wgpu::Extent3D size,
                                  wgpu::TextureFormat format,
                                  uint32_t mipLevelCount,
                                  uint32_t sampleCount) {
        wgpu::TextureDescriptor texDesc = {};
        texDesc.dimension = wgpu::TextureDimension::e2D;
        texDesc.size = size;
        texDesc.mipLevelCount = mipLevelCount;
        texDesc.format = format;
        texDesc.sampleCount = sampleCount;
        texDesc.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::CopySrc |
                        wgpu::TextureUsage::RenderAttachment | wgpu::TextureUsage::TextureBinding;
        return device.CreateTexture(&texDesc);
    }

    void DoTest() {
        DAWN_SUPPRESS_TEST_IF(IsWARP());
        // TODO(dawn:1859): Fix it on D3D11 Intel.
        DAWN_SUPPRESS_TEST_IF(IsD3D11() && IsIntel() && GetParam().mArrayLayerCount > 12);

        uint32_t width = GetParam().mTextureWidth;
        uint32_t height = GetParam().mTextureHeight;
        uint32_t depthOrArrayLayerCount = GetParam().mArrayLayerCount;
        uint32_t mipLevelCount = GetParam().mMipLevelCount;
        uint32_t sampleCount = GetParam().mSampleCount;
        wgpu::Extent3D textureSize = {width, height, depthOrArrayLayerCount};

        // Pre-allocate textures. The incorrect write type may corrupt neighboring textures or
        // layers.
        std::vector<wgpu::Texture> textures;
        wgpu::TextureFormat format = GetParam().mTextureFormat;
        uint32_t texNum = 2;
        for (uint32_t i = 0; i < texNum; ++i) {
            textures.push_back(Create2DTexture(textureSize, format, mipLevelCount, sampleCount));
        }

        // Multisample textures have only 1 layer, while other textures being tested have 2 layers
        // at least.
        std::vector<uint32_t> testedLayers = {0};
        if (sampleCount == 1) {
            testedLayers.push_back(1);
        }

        // Most 2d-array textures being tested have only 2 layers. But if the texture has a lot of
        // layers, select a few layers to test.
        if (depthOrArrayLayerCount > 2) {
            DAWN_ASSERT(sampleCount == 1);
            uint32_t divider = 4;
            for (uint32_t i = 1; i <= divider; ++i) {
                int32_t testedLayer = depthOrArrayLayerCount * i / divider - 1;
                if (testedLayer > 1) {
                    testedLayers.push_back(testedLayer);
                }
            }
        }

        // Write data and verify the result one by one for every layer of every texture
        uint32_t srcValue = 100000000;
        for (uint32_t i = 0; i < texNum; ++i) {
            for (uint32_t j = 0; j < testedLayers.size(); ++j) {
                for (uint32_t k = 0; k < mipLevelCount; ++k) {
                    DoSingleTest(textures[i], textureSize, testedLayers[j], k, sampleCount,
                                 srcValue, format)
                        << "texNum: " << i << ", layer: " << j << ", mip level: " << k;
                    srcValue += 100000000;
                }
            }
        }
    }
};

class TextureCorruptionTests_Format : public TextureCorruptionTests {};

TEST_P(TextureCorruptionTests_Format, Tests) {
    DoTest();
}

DAWN_INSTANTIATE_TEST_P(TextureCorruptionTests_Format,
                        {D3D11Backend(), D3D12Backend()},
                        {wgpu::TextureFormat::R8Unorm, wgpu::TextureFormat::RG8Unorm,
                         wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA16Uint,
                         wgpu::TextureFormat::RGBA32Uint, wgpu::TextureFormat::Depth16Unorm,
                         wgpu::TextureFormat::Stencil8},
                        {100u, 600u, 1200u, 2400u, 4800u},
                        {kDefaultHeight},
                        {kDefaultArrayLayerCount},
                        {kDefaultMipLevelCount},
                        {kDefaultSampleCount},
                        {WriteType::ClearTexture});

class TextureCorruptionTests_WidthAndHeight : public TextureCorruptionTests {};

TEST_P(TextureCorruptionTests_WidthAndHeight, Tests) {
    DoTest();
}

DAWN_INSTANTIATE_TEST_P(TextureCorruptionTests_WidthAndHeight,
                        {D3D11Backend(), D3D12Backend()},
                        {kDefaultFormat},
                        {100u, 200u, 300u, 400u, 500u, 600u, 700u, 800u, 900u, 1000u, 1200u},
                        {100u, 200u},
                        {kDefaultArrayLayerCount},
                        {kDefaultMipLevelCount},
                        {kDefaultSampleCount},
                        {kDefaultWriteType});

class TextureCorruptionTests_ArrayLayer : public TextureCorruptionTests {};

TEST_P(TextureCorruptionTests_ArrayLayer, Tests) {
    DoTest();
}

DAWN_INSTANTIATE_TEST_P(TextureCorruptionTests_ArrayLayer,
                        {D3D11Backend(), D3D12Backend()},
                        {kDefaultFormat},
                        {100u, 600u, 1200u},
                        {kDefaultHeight},
                        {6u, 12u, 40u, 256u},
                        {kDefaultMipLevelCount},
                        {kDefaultSampleCount},
                        {kDefaultWriteType});

class TextureCorruptionTests_Mipmap : public TextureCorruptionTests {};

TEST_P(TextureCorruptionTests_Mipmap, Tests) {
    DoTest();
}

DAWN_INSTANTIATE_TEST_P(TextureCorruptionTests_Mipmap,
                        {D3D11Backend(), D3D12Backend()},
                        {kDefaultFormat},
                        {100u, 600u, 1200u},
                        {kDefaultHeight},
                        {kDefaultArrayLayerCount},
                        {2u, 6u},
                        {kDefaultSampleCount},
                        {kDefaultWriteType});

class TextureCorruptionTests_Multisample : public TextureCorruptionTests {
  protected:
    std::ostringstream& DoSingleTest(wgpu::Texture texture,
                                     const wgpu::Extent3D textureSize,
                                     uint32_t depthOrArrayLayer,
                                     uint32_t mipLevel,
                                     uint32_t sampleCount,
                                     uint32_t srcValue,
                                     wgpu::TextureFormat format) override {
        DAWN_ASSERT(depthOrArrayLayer == 0);
        DAWN_ASSERT(mipLevel == 0);
        uint32_t bytesPerTexel = utils::GetTexelBlockSizeInBytes(format);

        return ExpectMultisampledFloatData(texture, textureSize.width, textureSize.height,
                                           bytesPerTexel, sampleCount, 0, mipLevel,
                                           new detail::ExpectConstant<float>(0));
    }
};

TEST_P(TextureCorruptionTests_Multisample, Tests) {
    DoTest();
}

DAWN_INSTANTIATE_TEST_P(TextureCorruptionTests_Multisample,
                        {D3D11Backend(), D3D12Backend()},
                        {kDefaultFormat},
                        {100u, 200u, 300u, 400u, 500u, 600u, 700u, 800u, 900u, 1000u, 1200u},
                        {100u, 200u},
                        {1u},
                        {kDefaultMipLevelCount},
                        {4u},
                        {WriteType::ClearTexture});

class TextureCorruptionTests_WriteType : public TextureCorruptionTests {};

TEST_P(TextureCorruptionTests_WriteType, Tests) {
    DoTest();
}

DAWN_INSTANTIATE_TEST_P(TextureCorruptionTests_WriteType,
                        {D3D11Backend(), D3D12Backend()},
                        {kDefaultFormat},
                        {100u, 600u, 1200u},
                        {kDefaultHeight},
                        {kDefaultArrayLayerCount},
                        {kDefaultMipLevelCount},
                        {kDefaultSampleCount},
                        {WriteType::ClearTexture, WriteType::WriteTexture, WriteType::B2TCopy,
                         WriteType::RenderConstant, WriteType::RenderFromTextureSample,
                         WriteType::RenderFromTextureLoad});

}  // anonymous namespace
}  // namespace dawn
